Guia para sincronização em Java
Publicados: 2022-10-23Antes de explicarmos a sincronização em Java , devemos revisitar brevemente o conceito de multithreading. O recurso multithreading do Java permite a execução simultânea de duas ou mais partes de um programa para utilização máxima da CPU. Cada parte de tal programa é um thread, e threads são processos leves dentro de um processo.
Agora, vários threads de um programa podem tentar acessar os mesmos recursos e produzir resultados imprecisos. Portanto, deve haver alguma sincronização para garantir que apenas um thread tenha acesso aos recursos em um determinado momento.
Confira nossos cursos de tecnologia gratuitos para obter uma vantagem sobre a concorrência.
Este guia sobre o que é sincronização em Java explorará o conceito de sincronização em detalhes com exemplos.
Aprenda cursos de desenvolvimento de software online das melhores universidades do mundo. Ganhe Programas PG Executivos, Programas de Certificado Avançado ou Programas de Mestrado para acelerar sua carreira.
O que é sincronização em Java?
A sincronização Java é a capacidade de controlar o acesso de vários threads a um recurso compartilhado. É útil quando programas Java multiencadeados tentam acessar o mesmo recurso e produzem resultados errôneos. Usando o recurso de sincronização Java, apenas um único encadeamento pode acessar o recurso em um determinado ponto de tempo.
Java fornece uma maneira de sincronizar a tarefa de threads usando blocos sincronizados que sincronizam no mesmo objeto e podem ter apenas um thread executando dentro deles por vez. Esses blocos são marcados com a palavra-chave sincronizada, bloqueando qualquer outra thread que tente entrar no bloco sincronizado até que a thread que já está dentro do bloco termine sua execução e saia do bloco.
Confira a Certificação Avançada do upGrad em DevOps
A sintaxe para escrever um bloco sincronizado
A sintaxe geral para escrever um bloco sincronizado em Java é a seguinte:
sincronizado( lockObject )
{
// instruções sincronizadas
}
Explore nossos cursos populares de engenharia de software
Mestre em Ciência da Computação pela LJMU & IIITB | Programa de Certificado de Segurança Cibernética Caltech CTME |
Curso de Desenvolvimento Full Stack | Programa PG em Blockchain |
Programa PG Executivo em Desenvolvimento Full Stack | |
Veja todos os nossos cursos abaixo | |
Cursos de Engenharia de Software |
Na sintaxe acima, lockObject refere-se a um objeto cujo bloqueio está relacionado aos elementos sincronizados. Agora, isso nos leva ao conceito de bloqueio em Java.
Confira a Certificação Avançada em Segurança Cibernética do upGrad
Bloqueios em Java
A sincronização em Java é construída em torno do bloqueio ou monitor. Cada objeto tem um bloqueio associado. Idealmente, um thread que requer acesso aos campos de um objeto deve primeiro obter o bloqueio do objeto. O bloqueio é um mecanismo de sincronização de thread mais sofisticado e flexível do que o bloco de sincronização. Ele é definido dentro do pacote java.util.concurrent.lock contendo extensas implementações de bloqueio.
Habilidades de desenvolvimento de software sob demanda
Cursos de JavaScript | Cursos básicos de Java | Cursos de Estruturas de Dados |
Cursos Node.js | Cursos de SQL | Cursos de desenvolvimento full stack |
Cursos NFT | Cursos de DevOps | Cursos de Big Data |
Cursos React.js | Cursos de segurança cibernética | Cursos de computação em nuvem |
Cursos de Design de Banco de Dados | Cursos de Python | Cursos de criptomoedas |
Método Sincronizado Java
A finalidade de um método sincronizado Java é bloquear objetos para recursos compartilhados. Assim, quando as threads invocam um método sincronizado, o método automaticamente obtém o bloqueio para esse objeto e o libera assim que a thread executa seu trabalho.
Aqui está um exemplo de um método sincronizado Java:
//exemplo de método java sincronizado
classe Tabela{
void printTable(int n){//método sincronizado sincronizado
for(int i=1;i<=5;i++){
System.out.println(n*i);
tentar{
Thread.sleep(400);
}catch(Exception e){System.out.println(e);}
}
}
}
class MyThread1 estende Thread{
Tábua;
MyThread1(Tabela t){
this.t=t;
}
public void executar(){
t.printTable(5);
}
}
class MyThread2 estende Thread{
Tábua;
MyThread2(Tabela t){
this.t=t;
}
public void executar(){
t.printTable(100);
}
}
classe pública TestSynchronization2{
public static void main(String args[]){
Table obj = new Table();//somente um objeto
MeuThread1 t1=novo MeuThread1(obj);
MeuThread2 t2=novo MeuThread2(obj);
t1.início();
t2.início();
}
}
Leia nossos artigos populares relacionados ao desenvolvimento de software
Como implementar a abstração de dados em Java? | O que é classe interna em Java? | Identificadores Java: Definição, Sintaxe e Exemplos |
Entendendo o encapsulamento em OOPS com exemplos | Argumentos de linha de comando em C explicados | Os 10 principais recursos e características da computação em nuvem em 2022 |
Polimorfismo em Java: Conceitos, Tipos, Características e Exemplos | Pacotes em Java e como usá-los? | Tutorial do Git para iniciantes: aprenda o Git do zero |
Resultado:
5
10
15
20
25
100
200
300
400
500
O que acontece sem sincronização?
Agora, vamos ver o programa anterior sem sincronização (observe a ausência da palavra-chave sincronizada).
classe Tabela{
void printTable(int n){//método não sincronizado
for(int i=1;i<=5;i++){
System.out.println(n*i);
tentar{
Thread.sleep(400);
}catch(Exception e){System.out.println(e);}
}
}
}
class MyThread1 estende Thread{
Tábua;
MyThread1(Tabela t){
this.t=t;
}
public void executar(){
t.printTable(5);
}
}
class MyThread2 estende Thread{
Tábua;
MyThread2(Tabela t){
this.t=t;
}
public void executar(){
t.printTable(100);
}
}
class TestSynchronization1{
public static void main(String args[]){
Table obj = new Table();//somente um objeto
MeuThread1 t1=novo MeuThread1(obj);
MeuThread2 t2=novo MeuThread2(obj);
t1.início();
t2.início();
}
}
Resultado:
5
100
10
200
15
300
20
400
25
500
Como você pode ver, a saída é inconsistente sem sincronização.
Tipos de sincronização em Java
Para responder o que é sincronização de threads em Java , temos dois tipos de sincronização disponíveis: sincronização de threads e sincronização de processos.
Vamos entender o que cada um significa.
Sincronização de threads: quando vários threads tentam acessar um recurso compartilhado, devemos garantir que o recurso seja usado por apenas um thread por vez. A sincronização de threads é o processo de permitir que apenas um thread use o recurso compartilhado quando vários threads estão tentando usar o recurso simultaneamente.
Sincronização de processos: Refere-se à execução simultânea de vários processos para atingir um estado em que os processos se comprometem com uma ordem de execução apropriada. A sincronização de processos é necessária quando dois ou mais processos cooperam e a execução de um processo afeta o outro. Assim, a sincronização de processos elimina a possibilidade de saídas imprecisas e garante a ordem de execução correta.
Métodos de sincronização em Java
Em termos gerais, existem quatro métodos de sincronização em Java:
- Métodos estáticos sincronizados
- Métodos de instância sincronizados
- Bloco sincronizado dentro de métodos estáticos
- Bloco sincronizado dentro de métodos de instância
Vejamos cada método de sincronização Java com mais detalhes.
Métodos estáticos sincronizados
Aqui, usamos a palavra-chave sincronizada para marcar os métodos estáticos em Java. Aqui está um exemplo de um método estático sincronizado Java:
public static MyStaticCounter {
contagem int estática privada = 0;
incremento nulo sincronizado estático público (valor int) {
contagem += valor;
}
}
Métodos de instância sincronizados
Ao usar um bloco sincronizado com métodos de instância, cada objeto tem seu método sincronizado. Cada objeto pode ter apenas um thread que pode ser executado dentro de um método. Se houver vários objetos, um único thread pode ser executado para cada objeto dentro do bloco.
classe pública MeuContador {
contagem de inteiros privados = 0;
incremento nulo sincronizado público (valor int) {
this.count += valor;
}
decremento void sincronizado público (valor int) {
this.count -= valor;
}
}
Bloco sincronizado dentro de métodos estáticos
Abaixo está um exemplo onde usamos um bloco sincronizado dentro de um método estático:
classe pública MinhaClasse {
public static void print(String message) {
sincronizado(MinhaClasse.classe) {
log.writeln(mensagem);
}
}
}
Bloco sincronizado dentro de métodos de instância
Em vez de sincronizar todo o método, podemos usar o sincronizado em um bloco específico dentro do método. Abaixo está um exemplo de um bloco de código sincronizado dentro de um método não sincronizado:
incremento void público (valor int) {
sincronizado(este) {
this.count += valor;
}
}
Necessidade de sincronização em Java
Agora que você sabe o que é sincronização em Java , você deve estar se perguntando por que nós a usamos em primeiro lugar.
A palavra-chave sincronizada do Java fornece funcionalidades essenciais para programação simultânea. Veja como a sincronização em Java ajuda:
- A sincronização Java fornece o recurso de bloqueio para eliminar qualquer condição de corrida entre threads e garantir acesso mutuamente exclusivo ao recurso compartilhado.
- O bloqueio sincronizado Java fornece os recursos de bloqueio e desbloqueio. Portanto, um thread precisa adquirir o bloqueio antes de inserir um método ou bloco sincronizado.
- A palavra-chave sincronizada impede a reordenação de instruções de programa pelo compilador.
Conclusão
Resumindo, a sincronização em Java garante que apenas um thread possa acessar o recurso compartilhado por vez. Podemos sincronizar um bloco ou método usando a palavra-chave sincronizada do Java. Quando uma thread deseja entrar em um bloco sincronizado, ela deve adquirir um bloqueio e, após sair do bloco, a thread libera o bloqueio. Podemos usar a palavra-chave sincronizada com métodos ou dentro do bloco de um método.
Você quer aprender os conceitos básicos em Java? O curso upGrad Executive Post Graduate Program in Software Development – Specialization in Full Stack Development é um programa online de 7 semanas para iniciantes que desejam explorar carreiras de desenvolvimento de software. Participe de aulas ao vivo e interativas, sessões práticas e mais de 35 horas de conteúdo ministrado por líderes do setor para obter um certificado de conclusão do upGrad.
Inscreva-se hoje para aproveitar os benefícios exclusivos do upGrad de suporte ao aluno 24 horas por dia, 7 dias por semana e rede do setor!
Por que usamos sincronizado em Java?
A palavra-chave sincronizada em Java garante que apenas um encadeamento possa acessar os recursos compartilhados por vez. É útil quando programas Java multiencadeados tentam acessar o mesmo recurso e produzem resultados imprecisos.
Como a sincronização é implementada em Java?
Java implementa a sincronização usando o conceito de monitores com apenas um thread possuindo um monitor em um determinado momento. Quando um encadeamento adquire um bloqueio, ele obtém acesso ao monitor e todos os outros encadeamentos que tentam entrar no monitor bloqueado permanecem bloqueados até que o primeiro encadeamento deixe o monitor.
O que é um impasse em Java?
O deadlock Java ocorre quando um thread está aguardando um bloqueio de objeto, mas outro thread o adquire e o segundo thread está aguardando um bloqueio de objeto adquirido pelo primeiro. Assim, ambas as threads esperam uma pela outra liberar o bloqueio, resultando em um impasse.