O que significa 'sincronizado'?

994

Tenho algumas perguntas sobre o uso e o significado da synchronizedpalavra - chave.

  • Qual é o significado da synchronizedpalavra - chave?
  • Quando devem ser os métodos synchronized?
  • O que significa programaticamente e logicamente?
Johanna
fonte
1
discussão útil entre hashmap e hashtable, e sincronização: stackoverflow.com/questions/40471/java-hashmap-vs-hashtable
LIMC
2
Possível duplicata Como é sincronizado trabalho em Java
Marian Paździoch
1
Passei por todo o link da documentação desde o primeiro comentário e não entendi até chegar ao último parágrafo. Em vez de colar links e não citar nada, pode ser colar links e adicionar uma cotação é mais útil.
Rakib

Respostas:

878

A synchronizedpalavra-chave se refere a diferentes segmentos de leitura e gravação nas mesmas variáveis, objetos e recursos. Este não é um tópico trivial em Java, mas aqui está uma citação da Sun:

synchronized Os métodos permitem uma estratégia simples para impedir a interferência do encadeamento e os erros de consistência da memória: se um objeto estiver visível para mais de um encadeamento, todas as leituras ou gravações nas variáveis ​​desse objeto serão feitas por métodos sincronizados.

Em poucas palavras: quando você tem dois threads que estão lendo e gravando no mesmo 'recurso', digamos uma variável chamada foo, é necessário garantir que esses threads acessem a variável de maneira atômica. Sem a synchronizedpalavra - chave, seu encadeamento 1 pode não ver o encadeamento de alteração 2 feito para foo, ou pior, pode ser apenas parcialmente alterado. Isso não seria o que você espera logicamente.

Novamente, este é um tópico não trivial em Java. Para saber mais, explore os tópicos aqui no SO e nas Interwebs sobre:

Continue explorando esses tópicos até o nome "Brian Goetz" se tornar permanentemente associado ao termo "simultaneidade" em seu cérebro.

Stu Thompson
fonte
71
Então, basicamente essa palavra-chave sincronizada torna seus métodos seguros para threads?
Rigo Vides
82
A palavra-chave sincronizada é uma das ferramentas que tornam seu encadeamento de código seguro. Apenas o uso sincronizado de um método ou variável por si só pode ou não fazer o truque. Ter um entendimento básico do Java Memory Model é realmente importante para obter a simultaneidade correta.
Stu Thompson
28
A menos que você seja Brian Goetz (ou talvez Jon Skeet), é quase impossível obter a simultaneidade Java correta apenas com os primitivos da linguagem (sincronizados, voláteis). Para iniciantes, use o pacote java.util.concurrent e construa sobre ele.
Thilo
12
Mais claramente: métodos sincronizados não podem ser chamados ao mesmo tempo a partir de vários threads.
peterh - Restabelece Monica 15/03
2
@peterh sincronizada faz mais do que, por conseguinte, a mais detalhada explicação
Stu Thompson
294

Bem, acho que tínhamos explicações teóricas suficientes, então considere este código

public class SOP {
    public static void print(String s) {
        System.out.println(s+"\n");
    }
}

public class TestThread extends Thread {
    String name;
    TheDemo theDemo;
    public TestThread(String name,TheDemo theDemo) {
        this.theDemo = theDemo;
        this.name = name;
        start();
    }
    @Override
    public void run() {
        theDemo.test(name);
    }
}

public class TheDemo {
    public synchronized void test(String name) {
        for(int i=0;i<10;i++) {
            SOP.print(name + " :: "+i);
            try{
                Thread.sleep(500);
            } catch (Exception e) {
                SOP.print(e.getMessage());
            }
        }
    }
    public static void main(String[] args) {
        TheDemo theDemo = new TheDemo();
        new TestThread("THREAD 1",theDemo);
        new TestThread("THREAD 2",theDemo);
        new TestThread("THREAD 3",theDemo);
    }
}

Nota: synchronizedbloqueia a chamada do próximo segmento ao método test () desde que a execução do segmento anterior não esteja concluída. Os threads podem acessar esse método, um de cada vez. Sem synchronizedtodos os threads, você pode acessar esse método simultaneamente.

Quando um thread chama o método sincronizado 'test' do objeto (aqui o objeto é uma instância da classe 'TheDemo') ele adquire o bloqueio desse objeto, qualquer novo thread não pode chamar QUALQUER método sincronizado do mesmo objeto, desde que o thread anterior que adquiriu a trava não libera a trava.

O mesmo ocorre quando qualquer método estático sincronizado da classe é chamado. O encadeamento adquire o bloqueio associado à classe (nesse caso, qualquer método sincronizado não estático de uma instância dessa classe pode ser chamado por qualquer encadeamento porque esse bloqueio no nível do objeto ainda está disponível). Qualquer outro encadeamento não poderá chamar nenhum método estático sincronizado da classe, desde que o bloqueio no nível da classe não seja liberado pelo encadeamento que atualmente mantém o bloqueio.

Saída com sincronizado

THREAD 1 :: 0
THREAD 1 :: 1
THREAD 1 :: 2
THREAD 1 :: 3
THREAD 1 :: 4
THREAD 1 :: 5
THREAD 1 :: 6
THREAD 1 :: 7
THREAD 1 :: 8
THREAD 1 :: 9
THREAD 3 :: 0
THREAD 3 :: 1
THREAD 3 :: 2
THREAD 3 :: 3
THREAD 3 :: 4
THREAD 3 :: 5
THREAD 3 :: 6
THREAD 3 :: 7
THREAD 3 :: 8
THREAD 3 :: 9
THREAD 2 :: 0
THREAD 2 :: 1
THREAD 2 :: 2
THREAD 2 :: 3
THREAD 2 :: 4
THREAD 2 :: 5
THREAD 2 :: 6
THREAD 2 :: 7
THREAD 2 :: 8
THREAD 2 :: 9

Saída sem sincronizado

THREAD 1 :: 0
THREAD 2 :: 0
THREAD 3 :: 0
THREAD 1 :: 1
THREAD 2 :: 1
THREAD 3 :: 1
THREAD 1 :: 2
THREAD 2 :: 2
THREAD 3 :: 2
THREAD 1 :: 3
THREAD 2 :: 3
THREAD 3 :: 3
THREAD 1 :: 4
THREAD 2 :: 4
THREAD 3 :: 4
THREAD 1 :: 5
THREAD 2 :: 5
THREAD 3 :: 5
THREAD 1 :: 6
THREAD 2 :: 6
THREAD 3 :: 6
THREAD 1 :: 7
THREAD 2 :: 7
THREAD 3 :: 7
THREAD 1 :: 8
THREAD 2 :: 8
THREAD 3 :: 8
THREAD 1 :: 9
THREAD 2 :: 9
THREAD 3 :: 9
Dheeraj Sachan
fonte
7
Ótimo exemplo, é bom conhecer a teoria, mas o código é sempre mais específico e completo.
Santi Iglesias
2
@SantiIglesias "Complete"? Não. Este exemplo demonstra o comportamento de bloqueio de synchronized, mas a consistência da memória é ignorada.
Stu Thompson
2
@Stu Thompson consistência de memória é o resultado de bloqueio
Dheeraj Sachan
@DheerajSachan Por essa lógica, o uso de um ReentrantLock resultaria em consistência de memória. Não faz.
Stu Thompson
3
@boltup_im_coding: O método start () coloca o Thread em um estado "RUNNABLE", o que significa que está pronto para execução ou já está em execução. Pode acontecer que outro encadeamento (geralmente mas não necessariamente com prioridade mais alta) no estado Runnable salte a fila e comece a executar. No exemplo acima, linha 3 aconteceu para obter CPU antes ROSCA 2.
Sahil J
116

A synchronizedpalavra-chave impede o acesso simultâneo a um bloco de código ou objeto por vários encadeamentos. Todos os métodos de Hashtablesão synchronized, portanto, apenas um encadeamento pode executar qualquer um deles por vez.

Ao usar não- synchronizedconstruções como HashMap, você deve criar recursos de segurança de thread em seu código para evitar erros de consistência.

jmort253
fonte
81

synchronized significa que em um ambiente multiencadeado, um objeto com synchronized método (s) / bloco (s) não permite que dois threads acessem o synchronized(s) método (s) / bloco (s) de código ao mesmo tempo. Isso significa que um thread não pode ler enquanto outro thread o atualiza.

O segundo thread aguardará até que o primeiro thread conclua sua execução. A sobrecarga é a velocidade, mas a vantagem é a consistência garantida dos dados.

Se seu aplicativo for de thread único, synchronized blocos não oferecem benefícios.

Codemwnci
fonte
54

o synchronized palavra-chave faz com que um encadeamento obtenha um bloqueio ao inserir o método, para que apenas um encadeamento possa executar o método ao mesmo tempo (para a instância do objeto especificada, a menos que seja um método estático).

Isso é chamado frequentemente de tornar a classe segura para threads, mas eu diria que isso é um eufemismo. Embora seja verdade que a sincronização protege o estado interno do vetor de ser corrompido, isso geralmente não ajuda muito o usuário do vetor.

Considere isto:

 if (vector.isEmpty()){
     vector.add(data);
 }

Embora os métodos envolvidos sejam sincronizados, porque estão sendo bloqueados e desbloqueados individualmente, infelizmente dois threads cronometrados podem criar um vetor com dois elementos.

Portanto, você também precisa sincronizar o código do aplicativo.

Como a sincronização no nível do método é a) cara quando você não precisa eb) insuficiente quando precisa da sincronização, agora existem substituições não sincronizadas (ArrayList no caso de Vector).

Mais recentemente, o pacote de simultaneidade foi lançado, com vários utilitários inteligentes que cuidam de problemas com vários threads.

Thilo
fonte
27

Visão geral

A palavra-chave sincronizada em Java tem a ver com segurança de encadeamento, ou seja, quando vários encadeamentos lêem ou gravam a mesma variável.
Isso pode acontecer diretamente (acessando a mesma variável) ou indiretamente (usando uma classe que usa outra classe que acessa a mesma variável).

A palavra-chave sincronizada é usada para definir um bloco de código no qual vários threads podem acessar a mesma variável de maneira segura.

Mais profundo

Em termos de sintaxe, a synchronizedpalavra-chave recebe um Objectparâmetro como é (chamado de objeto de bloqueio ), que é seguido por a { block of code }.

  • Quando a execução encontra essa palavra-chave, o encadeamento atual tenta "bloquear / adquirir / possuir" (faça a sua escolha) o objeto de bloqueio e execute o bloco de código associado após a aquisição do bloqueio.

  • Qualquer gravação em variáveis ​​dentro do bloco de código sincronizado é garantida para ser visível para todos os outros encadeamentos que executam código de forma semelhante dentro de um bloco de código sincronizado usando o mesmo objeto de bloqueio .

  • Somente um encadeamento de cada vez pode reter o bloqueio, durante o qual todos os outros encadeamentos que tentam adquirir o mesmo objeto de bloqueio aguardam (pausam sua execução). O bloqueio será liberado quando a execução sair do bloco de código sincronizado.

Métodos sincronizados:

Adicionando synchronizedpalavra-chave para uma definição do método é igual a todo o corpo do método a ser enrolado num bloco de código sincronizado com o bloqueio objeto ser this (para os métodos de instância) e ClassInQuestion.getClass() (para os métodos da classe) .

- Método de instância é um método que não possui staticpalavra-chave.
- Método de classe é um método que possui staticpalavra - chave.

Técnico

Sem sincronização, não é garantido em que ordem as leituras e gravações acontecem, possivelmente deixando a variável com lixo.
(Por exemplo, uma variável pode acabar com metade dos bits gravados por um thread e metade dos bits gravados por outro thread, deixando a variável em um estado que nenhum dos threads tentou escrever, mas uma bagunça combinada de ambos.)

Não é suficiente concluir uma operação de gravação em um encadeamento antes (hora do relógio da parede) de outro encadeamento, porque o hardware poderia ter armazenado em cache o valor da variável e o encadeamento de leitura veria o valor em cache em vez do que foi gravado em isto.

Conclusão

Portanto, no caso de Java, você deve seguir o Java Memory Model para garantir que os erros de segmentação não ocorram.
Em outras palavras: use sincronização, operações atômicas ou classes que as utilizem sob o capô.

Fontes

http://docs.oracle.com/javase/specs/jls/se8/html/index.html
Java® Language Specification, 13-02-2015

Gima
fonte
Desculpe, mas tenho este exemplo e não entendo o significado: `Inteiro i1 = Arrays.asList (1,2,3,4,5) .stream (). FindAny (). Get (); sincronizado (i1) {Inteiro i2 = Arrays.asList (6,7,8,9,10) .parallelStream () .sorted () .findAny (). get (); System.out.println (i1 + "" + i2); } `1. Por que você invocou o bloco na primeira instância e esta invocação não afeta o código? 2. A segunda instância será segura para threads, apesar da invocação do bloco na primeira?
precisa saber é o seguinte
1
@ Adryr83 Se você tiver uma pergunta, provavelmente poderá fazê-la postando uma nova pergunta. Mas como estamos aqui, analisarei o que puder (sua pergunta é um pouco difícil de entender). Pelo que posso dizer sobre esse trecho de código, ele não parece conter nada que exija sincronização. Está fora de contexto. Sugestão: Se puder, tente dividir o código em partes individuais menores e, em seguida, procure respostas sobre elas. É muito mais fácil tentar entender problemas pequenos e isolados do que tentar descobrir um grande bloco de código.
Gima
21

Pense nisso como uma espécie de catraca como você pode encontrar em um campo de futebol. Existem vapores paralelos de pessoas que querem entrar, mas na catraca são "sincronizados". Somente uma pessoa de cada vez pode passar. Todos aqueles que desejam passar o farão, mas podem ter que esperar até que possam passar.

Paulo
fonte
16

Qual é a palavra-chave sincronizada?

Os encadeamentos se comunicam principalmente compartilhando o acesso aos campos e os campos de referência de objetos a que se referem. Essa forma de comunicação é extremamente eficiente, mas possibilita dois tipos de erros: interferência de encadeamento e erros de consistência de memória . A ferramenta necessária para evitar esses erros é a sincronização.

Os blocos ou métodos sincronizados evitam a interferência do encadeamento e asseguram que os dados sejam consistentes. A qualquer momento, apenas um encadeamento pode acessar um método ou bloco sincronizado ( seção crítica ) adquirindo um bloqueio. Outras threads aguardam a liberação do bloqueio para acessar a seção crítica .

Quando os métodos são sincronizados?

Os métodos são sincronizados quando você adiciona synchronizedà definição ou declaração do método. Você também pode sincronizar um bloco de código específico com um método.

O que significa de forma programática e lógica?

Isso significa que apenas um encadeamento pode acessar a seção crítica adquirindo um bloqueio. A menos que esse thread libere esse bloqueio, todos os outros threads precisarão esperar para adquirir um bloqueio. Eles não têm acesso para entrar na seção crítica sem adquirir a trava.

Isso não pode ser feito com uma mágica. É responsabilidade do programador identificar seções críticas no aplicativo e protegê-lo adequadamente. O Java fornece uma estrutura para proteger seu aplicativo, mas onde e o que todas as seções a serem protegidas são de responsabilidade do programador.

Mais detalhes na página de documentação do java

Bloqueios intrínsecos e sincronização:

A sincronização é criada em torno de uma entidade interna conhecida como bloqueio intrínseco ou bloqueio do monitor. Os bloqueios intrínsecos desempenham um papel nos dois aspectos da sincronização: impor acesso exclusivo ao estado de um objeto e estabelecer relacionamentos anteriores ao passado, essenciais para a visibilidade.

Todo objeto tem um bloqueio intrínseco associado a ele . Por convenção, um encadeamento que precisa de acesso exclusivo e consistente aos campos de um objeto precisa adquirir o bloqueio intrínseco do objeto antes de acessá-los e liberar o bloqueio intrínseco quando terminar com eles.

Diz-se que uma linha possui a trava intrínseca entre o momento em que ela adquiriu a trava e a liberou. Desde que um encadeamento possua um bloqueio intrínseco, nenhum outro encadeamento poderá adquirir o mesmo bloqueio. O outro encadeamento será bloqueado quando tentar obter o bloqueio.

Quando um encadeamento libera um bloqueio intrínseco, é estabelecido um relacionamento de antes do início entre essa ação e qualquer aquisição subsequente do mesmo bloqueio.

A sincronização de métodos tem dois efeitos :

Primeiro, não é possível intercalar duas invocações de métodos sincronizados no mesmo objeto.

Quando um encadeamento está executando um método sincronizado para um objeto, todos os outros encadeamentos que invocam métodos sincronizados para o mesmo bloco de objeto (suspender a execução) até que o primeiro encadeamento seja concluído com o objeto.

Segundo, quando um método sincronizado sai, ele estabelece automaticamente um relacionamento de antes do acontecimento com qualquer chamada subsequente de um método sincronizado para o mesmo objeto.

Isso garante que as alterações no estado do objeto sejam visíveis para todos os threads.

Procure outras alternativas para sincronização em:

Evitar sincronizado (isso) em Java?

Ravindra babu
fonte
11

Synchronized normal methodequivalente a Synchronized statement(use isso)

class A {
    public synchronized void methodA() {
        // all function code
    }

    equivalent to

    public void methodA() {
        synchronized(this) {
             // all function code
        }
    } 
}

Synchronized static methodequivalente a Synchronized statement(use class)

class A {
    public static synchronized void methodA() {
        // all function code
    }

    equivalent to

    public void methodA() {
        synchronized(A.class) {
             // all function code
        }
    } 
}

Instrução sincronizada (usando variável)

class A {
    private Object lock1 = new Object();

    public void methodA() {
        synchronized(lock1 ) {
             // all function code
        }
    } 
}

Pois synchronized, temos ambos Synchronized Methodse Synchronized Statements. No entanto, Synchronized Methodsé semelhante ao Synchronized Statementsque precisamos entender Synchronized Statements.

=> Basicamente, teremos

synchronized(object or class) { // object/class use to provides the intrinsic lock
   // code 
}

Aqui estão 2 que ajudam a entender synchronized

  • Todo objeto / classe tem um intrinsic lockassociado a ele.
  • Quando um thread invoca um synchronized statement, adquire automaticamente o intrinsic lockpara esse synchronized statement'sobjeto e libera-lo quando o método retorna. Enquanto um segmento possuir um intrinsic lock, nenhum outro segmento poderá adquirir o SAME lock => thread safe.

=> Quando um thread Ainvoca synchronized(this){// code 1}=> todo o código de bloco (classe interna) onde have synchronized(this)e all synchronized normal method(classe interna) estão bloqueados porque o mesmo bloqueio. Ele será executado após o thread Adesbloqueio ("// código 1" concluído).

Esse comportamento é semelhante a synchronized(a variable){// code 1}ou synchronized(class).

SAME LOCK => lock (não depende de qual método? Ou de quais instruções?)

Usar método sincronizado ou instruções sincronizadas?

Eu prefiro synchronized statementsporque é mais extensível. Por exemplo, no futuro, você só precisa sincronizar uma parte do método. Por exemplo, você tem 2 métodos sincronizados e eles não são relevantes um para o outro; no entanto, quando um thread executa um método, ele bloqueia o outro método (pode ser impedido pelo uso synchronized(a variable)).

No entanto, aplicar o método sincronizado é simples e o código parece simples. Para algumas classes, existe apenas um método sincronizado, ou todos os métodos sincronizados na classe, relevantes entre si => podemos usar synchronized methodpara tornar o código mais curto e fácil de entender

Nota

(isso não é relevante para muitos synchronized, é a diferença entre objeto e classe ou não estático e estático).

  • Quando você usa synchronizedo método normal ou synchronized(this)ousynchronized(non-static variable) ele será sincronizado com base em cada instância do objeto.
  • Quando você usa synchronizedum método estático ou synchronized(class)ou synchronized(static variable)ele será sincronizado com base na classe

Referência

https://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html https://docs.oracle.com/javase/tutorial/essential/concurrency/locksync.html

Espero que ajude

Phan Van Linh
fonte
11

Aqui está uma explicação de The Java Tutorials .

Considere o seguinte código:

public class SynchronizedCounter {
    private int c = 0;

    public synchronized void increment() {
        c++;
    }

    public synchronized void decrement() {
        c--;
    }

    public synchronized int value() {
        return c;
    }
}

if counté uma instância de SynchronizedCounter, a sincronização desses métodos tem dois efeitos:

  • Primeiro, não é possível intercalar duas invocações de métodos sincronizados no mesmo objeto. Quando um encadeamento está executando um método sincronizado para um objeto, todos os outros encadeamentos que invocam métodos sincronizados para o mesmo bloco de objetos (suspender a execução) até que o primeiro encadeamento seja concluído com o objeto.
  • Segundo, quando um método sincronizado sai, ele estabelece automaticamente um relacionamento de antes do acontecimento com qualquer chamada subsequente de um método sincronizado para o mesmo objeto. Isso garante que as alterações no estado do objeto sejam visíveis para todos os threads.
Shahryar Saljoughi
fonte
9

Para meu entendimento, sincronizado basicamente significa que o compilador escreve um monitor.enter e monitor.exit em torno do seu método. Como tal, pode ser seguro para threads, dependendo de como é usado (o que quero dizer é que você pode escrever um objeto com métodos sincronizados que não são seguros para threads, dependendo do que sua classe faz).

Spence
fonte
5

O que as outras respostas estão faltando é um aspecto importante: barreiras à memória . A sincronização de threads consiste basicamente em duas partes: serialização e visibilidade. Aconselho a todos que pesquisem no Google por "barreira da memória jvm", pois é um tópico não trivial e extremamente importante (se você modificar dados compartilhados acessados ​​por vários threads). Feito isso, aconselho a olhar para as classes do pacote java.util.concurrent que ajudam a evitar o uso da sincronização explícita, o que, por sua vez, ajuda a manter os programas simples e eficientes, talvez até a impedir conflitos.

Um exemplo é ConcurrentLinkedDeque . Juntamente com o padrão de comando, ele permite criar encadeamentos de trabalho altamente eficientes, inserindo os comandos na fila simultânea - sem necessidade de sincronização explícita, sem bloqueios possíveis, sem interrupção explícita (), basta pesquisar a fila chamando take ().

Resumindo: a "sincronização de memória" ocorre implicitamente quando você inicia um thread, um thread termina, você lê uma variável volátil, desbloqueia um monitor (deixa um bloco / função sincronizada) etc. Essa "sincronização" afeta (em certo sentido) as descargas ") todas as gravações feitas antes dessa ação específica. No caso do ConcurrentLinkedDeque mencionado acima , a documentação "diz":

Efeitos de consistência de memória: como em outras coleções simultâneas, as ações em um encadeamento anterior à colocação de um objeto em um ConcurrentLinkedDeque acontecem antes das ações subseqüentes ao acesso ou remoção desse elemento do ConcurrentLinkedDeque em outro encadeamento.

Esse comportamento implícito é um aspecto um tanto pernicioso, porque a maioria dos programadores Java sem muita experiência precisará de muito do que foi dado por causa disso. E, de repente, tropeça nesse encadeamento depois que o Java não está fazendo o que "deveria" fazer na produção, onde há uma carga de trabalho diferente - e é muito difícil testar problemas de simultaneidade.

user1050755
fonte
3

Sincronizado significa simplesmente que vários encadeamentos, se associados a um único objeto, podem impedir a leitura e gravação sujas se o bloco sincronizado for usado em um objeto específico. Para dar mais clareza, vamos dar um exemplo:

class MyRunnable implements Runnable {
    int var = 10;
    @Override
    public void run() {
        call();
    }

    public void call() {
        synchronized (this) {
            for (int i = 0; i < 4; i++) {
                var++;
                System.out.println("Current Thread " + Thread.currentThread().getName() + " var value "+var);
            }
        }
    }
}

public class MutlipleThreadsRunnable {
    public static void main(String[] args) {
        MyRunnable runnable1 = new MyRunnable();
        MyRunnable runnable2 = new MyRunnable();
        Thread t1 = new Thread(runnable1);
        t1.setName("Thread -1");
        Thread t2 = new Thread(runnable2);
        t2.setName("Thread -2");
        Thread t3 = new Thread(runnable1);
        t3.setName("Thread -3");
        t1.start();
        t2.start();
        t3.start();
    }
}

Criamos dois objetos de classe MyRunnable, sendo runnable1 compartilhado com o thread 1 e thread 3 e runnable2 sendo compartilhados apenas com o thread 2. Agora, quando t1 e t3 são iniciados sem o uso sincronizado, a saída PFB sugere que os dois segmentos 1 e 3 afetam simultaneamente o valor var, onde no segmento 2, var possui sua própria memória.

Without Synchronized keyword

    Current Thread Thread -1 var value 11
    Current Thread Thread -2 var value 11
    Current Thread Thread -2 var value 12
    Current Thread Thread -2 var value 13
    Current Thread Thread -2 var value 14
    Current Thread Thread -1 var value 12
    Current Thread Thread -3 var value 13
    Current Thread Thread -3 var value 15
    Current Thread Thread -1 var value 14
    Current Thread Thread -1 var value 17
    Current Thread Thread -3 var value 16
    Current Thread Thread -3 var value 18

Usando o Synchronzied, o thread 3 aguarda a conclusão do thread 1 em todos os cenários. Existem dois bloqueios adquiridos, um no runnable1 compartilhado pelo thread 1 e no thread 3 e outro no runnable2 compartilhado apenas pelo thread 2.

Current Thread Thread -1 var value 11
Current Thread Thread -2 var value 11
Current Thread Thread -1 var value 12
Current Thread Thread -2 var value 12
Current Thread Thread -1 var value 13
Current Thread Thread -2 var value 13
Current Thread Thread -1 var value 14
Current Thread Thread -2 var value 14
Current Thread Thread -3 var value 15
Current Thread Thread -3 var value 16
Current Thread Thread -3 var value 17
Current Thread Thread -3 var value 18
paras4all
fonte
Sincronizado significa ainda mais que isso: tem um impacto profundo na barreira da memória.
user1050755
1

Sincronizado simples significa que não há dois segmentos que possam acessar o bloco / método simultaneamente. Quando dizemos que qualquer bloco / método de uma classe está sincronizado, significa que apenas um thread pode acessá-los por vez. Internamente, o encadeamento que tenta acessá-lo primeiro bloqueia esse objeto e, enquanto esse bloqueio não estiver disponível, nenhum outro encadeamento poderá acessar qualquer um dos métodos / blocos sincronizados dessa instância da classe.

Observe que outro encadeamento pode acessar um método do mesmo objeto que não está definido para ser sincronizado. Um encadeamento pode liberar o bloqueio chamando

Object.wait()
Aniket Thakur
fonte
0

synchronizedO bloco em Java é um monitor em multithreading. synchronizedbloco com o mesmo objeto / classe pode ser executado por apenas um thread, todos os outros estão aguardando. Pode ajudar na race conditionsituação em que vários threads tentam atualizar a mesma variável (a primeira etapa é usar volatileAbout )

Java 5estendido synchronizedapoiando happens-before[Sobre]

Um desbloqueio (saída sincronizada de bloco ou método) de um monitor ocorre antes de cada bloqueio subsequente (entrada sincronizada de bloco ou método) desse mesmo monitor.

O próximo passo é java.util.concurrent

volátil vs sincronizado

yoAlex5
fonte
-6

sincronizada é uma palavra-chave em Java usada para fazer acontecer antes do relacionamento no ambiente de multithreading para evitar inconsistência de memória e erro de interferência de encadeamento.

Sharad
fonte