Variável final e bloco sincronizado em java
-
21-09-2019 - |
Pergunta
O que é uma variável final em Java?Por exemplo:se eu escrever final int temp;
em função, qual é o significado da palavra-chave final?
Além disso, quando eu gostaria de usar a variável final (tanto como variável de classe quanto como variável de função)?
Por que as variáveis em um bloco sincronizado devem ser declaradas como finais?
Solução
Basicamente, significa apenas que você não pode alterar o valor.Para variáveis de instância, você deve atribuir quaisquer variáveis finais uma vez (e apenas uma vez) no construtor (ou com um inicializador de variável).A sincronização é um conceito bastante ortogonal.
A principal razão para fazer uma local variável final é para que você possa usá-la em uma classe interna anônima...isso não tem nada a ver com estar em um bloco sincronizado.
Variáveis finais são útil para classes imutáveis, é certo - e a imutabilidade torna a vida mais fácil em um ambiente multithread - mas essa é a única relação entre os dois que consigo pensar ...
EDITAR:O comentário de Wildwezyr faz sentido em termos de não alterar a variável no qual você está sincronizando.Isso seria perigoso, pelas razões que ele apresentou.É isso que você quis dizer com "variável no bloco sincronizado"?
Outras dicas
Variáveis finais e blocos de código sincronizados têm algo em comum...Se você declarar uma variável não final a
e depois escreva synchronized (a) { System.out.println('xxx'); }
você receberá o aviso "Sincronização em campo não final" - pelo menos no NetBeans.
Por que você não deveria sincronizar em campos não finais?Porque se o valor do campo puder mudar, diferentes threads poderão estar sincronizando em diferentes objetos (diferentes valores do campo) - portanto, não poderá haver sincronização alguma (cada thread pode entrar no bloco sincronizado ao mesmo tempo).
Veja aqui um exemplo de problema real causado pela sincronização em um campo não final: http://forums.sun.com/thread.jspa?threadID=5379204
Além do que disse Jon Skeet, o valor não pode ser alterado, mas o conteúdo pode ser alterado.
final Integer one = new Integer(1);
...
one = new Integer(2); // compile error
final List list = new ArrayList();
...
list = new ArrayList(); // compile error
list.add(1); // Changes list, but that's fine!
Esteja ciente também de que final e final estático não são a mesma coisa.final está dentro do escopo da instância, enquanto static final é o mesmo para todas as instâncias de uma classe (em outras linguagens isso poderia ser chamado de constante).
Pessoalmente, acho que a vantagem de final, mesmo quando não é absolutamente necessária para que seu software funcione, está no significado semântico.Oferece a possibilidade de dizer ao compilador e a próxima pessoa trabalhando nesse código que esta variável não deve ser alterada e que tentar alterá-la pode resultar em um bug.