Pergunta

Qual é a diferença entre um método sincronizado e sincronizados bloco em Java ?

Fui pesquisar a resposta na Net, as pessoas parecem ser tão inseguro sobre isso :-(

Na minha opinião, seria que não há diferença entre os dois, exceto que a sincronização bloco pode ser mais localizada no escopo e, portanto, o bloqueio será de menor tempo ??

E em caso de Bloqueio de um método estático, sobre o que é o Bloqueio de tomadas ?Qual é o significado de um Bloqueio na Classe ?

Foi útil?

Solução

Um método sincronizado usa o receptor do método como um bloqueio (ou seja, this para métodos não estáticos e a classe anexante para métodos estáticos). Synchronized Blocks usa a expressão como uma trava.

Portanto, os dois métodos a seguir são equivalentes ao bloqueio de prospectivos:

synchronized void mymethod() { ... }

void mymethod() {
  synchronized (this) { ... }
}

Para métodos estáticos, a classe será bloqueada:

class MyClass {
  synchronized static mystatic() { ... }

  static mystaticeq() {
    syncrhonized (MyClass.class) { ... }
  }
}

Para blocos sincronizados, você pode usar qualquer nãonull Objeto como um bloqueio:

synchronized (mymap) {
  mymap.put(..., ...);
}

Escopo de bloqueio

Para métodos sincronizados, a trava será mantida em todo o escopo do método, enquanto no synchronized Bloco, o bloqueio é mantido apenas durante o escopo do bloco (também conhecido como seção crítica). Na prática, a JVM pode otimizar removendo algumas operações do synchronized Bloqueie a execução se puder provar que pode ser feito com segurança.

Outras dicas

Um método sincronizado é abreviado. Este:

class Something {
    public synchronized void doSomething() {
        ...
    }

    public static synchronized void doSomethingStatic() {
        ...
    }
}

é, para todos os efeitos, equivalente a isso:

class Something {
    public void doSomething() {
        synchronized(this) {
            ...
        }
    }

    public static void doSomethingStatic() {
        synchronized(Something.class) {
            ...
        }
    }
}

(Onde Something.class é o objeto de classe para a classe Something.)

Assim, com um bloco sincronizado, você pode ser mais específico sobre o seu bloqueio e mais grãos finos quando quiser usá-lo, mas fora isso não há diferença.

Sim, isso é uma diferença. O outro é que você pode adquirir uma trava em outros objetos além this.

A principal diferença é a seguinte: se você declarar um método a ser sincronizado, todo o corpo do método será sincronizado; Se você usar o bloco sincronizado, no entanto, poderá cerca apenas a "seção crítica" do método no bloco sincronizado, deixando o restante do método para fora do bloco.

Se todo o método fizer parte da seção crítica, não haverá diferença efetivamente. Se não for esse o caso, você deve usar um bloco sincronizado em torno da seção crítica. Quanto mais declarações você tiver em um bloco sincronizado, menos o paralelismo você recebe, então você deseja mantê -los no mínimo.

Um método sincronizado trava na instância do objeto em que o método está contido.

Onde um bloco sincronizado pode travar em qualquer objeto - normalmente um obito mutex definido como uma variável de instância. Isso permite mais controle sobre quais bloqueios estão em operação.

Na minha opinião, seria que não há diferença entre os dois, exceto que a sincronização bloco pode ser mais localizada no escopo e, portanto, o bloqueio será de menor tempo ??

Sim.Você está certo.Ao contrário de synchronized métodos sincronizados instruções tem de especificar o objeto que fornece a intrínseca de bloqueio.

Exemplo de java tutorial:

public void addName(String name) {
    synchronized(this) {
        lastName = name;
        nameCount++;
    }
    nameList.add(name);
}

Sincronizado demonstrações também são úteis para melhorar a simultaneidade com granulação fina a sincronização.Você pode encontrar um bom exemplo sobre o mesmo tutorial para abaixo de caso de uso.

Suponha, por exemplo, classe MsLunch tem dois campos de instância, c1 e c2, que nunca são usados juntos.Todas as atualizações de um desses campos deve ser synchronized, mas não há nenhuma razão para impedir que uma atualização de c1 de ser intercalada com uma atualização de c2 — e fazendo isso, reduz-se a simultaneidade, a criação desnecessária de bloqueio. Em vez de utilizar métodos sincronizados ou de outra forma usar o bloqueio associado a isso, vamos criar dois objetos exclusivamente para fornecer bloqueios de.

E em caso de Bloqueio de um método estático, sobre o que é o Bloqueio de tomadas ?Qual é o significado de um Bloqueio na Classe ?

Neste caso, o segmento adquire a intrínseca de bloqueio para a Classe de objeto associado com a classe.Assim, o acesso à classe estático de campos é controlado por um bloqueio que é distinto do bloqueio para qualquer instância da classe.

Quando você faz um método como sincronizado ( não static ) :

Não é possível que duas invocações de synchronized métodos do mesmo objeto para intercalar.Quando uma thread está em execução um método sincronizado para um objeto, todas as outras threads que invocar métodos sincronizados para o mesmo objeto (bloco de suspender a execução) até que o primeiro segmento é feito com o objeto.

Se você fizer um método como static synchronized :

Não é possível que duas invocações de static synchronized métodos em diferentes objetos da mesma classe intercalar.Quando uma thread está em execução um static synchronized método para um objeto da Classe A, todas as outras threads que invocar static synchronized métodos em qualquer um dos objetos da Classe de Um bloco (suspensão da execução) até que o primeiro segmento é feito com a execução do método.

Você encontra as melhores alternativas para a sincronização isso SE pergunta:

Evitar synchronized(this) em Java?

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top