método com variaveis final e threads

9 respostas
L

Olá pessoal

O que acontece com variaveis final ou parâmetros final dentro de um método não sincronizado quando este método esta sendo acessado por duas ou mais thread simultâneamente?

Obrigado!

9 Respostas

E

Depende.

Se as variáveis final forem de tipos primitivos ou então de tipos que são imutáveis (como String), não deve haver nenhum problema com concorrência.

Entretanto, se o tipo dessas variáveis não for imutável (um exemplo clássico é o de um StringBuffer), então pode haver problemas sim. É sempre necessário fazer a análise correta antes de afirmar algo categoricamente.

L

entanglement:
Depende.

Se as variáveis final forem de tipos primitivos ou então de tipos que são imutáveis (como String), não deve haver nenhum problema com concorrência.

Entretanto, se o tipo dessas variáveis não for imutável (um exemplo clássico é o de um StringBuffer), então pode haver problemas sim. É sempre necessário fazer a análise correta antes de afirmar algo categoricamente.

Somente de tipos primitivos.

Mas eu queria saber se a vm abre um contexto diferente(uma nova variável) para cada thread.

E

Não.

L

Mas o que acontece?

Se a variavel é final o seu valor não muda e a outra thread não pode atribuir nenhum valor nela.

E

A referência não pode ser alterada, mas se ela se refere a um objeto que pode ser alterado, você pode ter problemas.

Vou dar um exemplo bobo.

Digamos que você tenha algo como:

private static final StringBuffer sb = new StringBuffer();

Ninguém pode mudar qual o objeto ao qual sb se refere (ele foi alocado na hora em que a classe que contém essa declaração foi carregada e não vai ser mais modificado), mas o objeto em si contém um valor que pode ser alterado por algum dos métodos “append”, “delete”, “insert”, “setLength” etc.

Se duas threads estiverem acessando o objeto apontado por “sb” ao mesmo tempo, podemos ter o caso em que uma delas insere alguma coisa e outra deleta outra coisa. Então você pode ter problemas de acesso simultâneo mesmo sendo a variável definida como “static final”.

L

entanglement:
A referência não pode ser alterada, mas se ela se refere a um objeto que pode ser alterado, você pode ter problemas.

Vou dar um exemplo bobo.

Digamos que você tenha algo como:

private static final StringBuffer sb = new StringBuffer();

Ninguém pode mudar qual o objeto ao qual sb se refere (ele foi alocado na hora em que a classe que contém essa declaração foi carregada e não vai ser mais modificado), mas o objeto em si contém um valor que pode ser alterado por algum dos métodos “append”, “delete”, “insert”, “setLength” etc.

Se duas threads estiverem acessando o objeto apontado por “sb” ao mesmo tempo, podemos ter o caso em que uma delas insere alguma coisa e outra deleta outra coisa. Então você pode ter problemas de acesso simultâneo mesmo sendo a variável definida como “static final”.

Obrigado.

Isto eu já sabia.

Mas por exemplo:

public int metodo(int param){ final int x = param; return x; }

O que acontece com x quando duas ou mais threads entra no método?

L

Alexsandro89:
Alguem poderia me ajudar enquanto a isso ?!

  1. Simulação de Atendimento Bancário (Aplicação de FILA)

Obs.:

  • Devem ser seguidos os princípios e características de funcionamento do TAD, ou
    seja, FIFO ou FILO. Os métodos da Pilha e Fila não devem ser alterados. A lógica do
    problema deve ser escrita na classe principal que contenha o método estático main
    utilizando o TAD.
  • Se necessário, altere o TAD Pilha e Fila para que possam armazenar corretamente os
    dados, ou seja, o conteúdo de cada posição de acordo com o pedido, por exemplo,
    string ou Cliente.
  • A implementação deve ser feita em linguagem Java;

Simulação de Atendimento Bancário

Deverá implementar um algoritmo que determine o tempo médio que um cliente
permanece na fila de uma agência bancária. Quando um cliente entra na fila, o horário é
anotado. Quando ele sai, o tempo que ele permaneceu na fila é calculado e adicionado ao
tempo total de espera. Assim, no final do expediente, é possível determinar quanto tempo,
em média, cada cliente teve que aguardar para ser atendido.
Cenário da Simulação

Na agência há três guichês que atendem a uma única fila de clientes. À medida que um
deles ficar livre, o primeiro cliente da fila o utiliza.

Há apenas duas entidades envolvidas na simulação: guichês e clientes. Tudo o que é
necessário saber sobre um guichê é se ele está ocupado e, caso esteja, por quanto tempo
permanecerá ocupado. Inicialmente, todos os guichês estão livres. Quando um cliente inicia
uma transação num deles, o tempo médio necessário para a realização da transação
determina por quanto tempo o guichê permanecerá ocupado.

Transação Código Tempo Médio

Saque 0 60 segundos
Depósito 1 90 segundos
Pagamento 2 120 segundos

Sobre o cliente, só é necessário saber quando ele entrou na fila para que, ao sair, seja
possível calcular quanto tempo ele permaneceu nela.
Algoritmo de Simulação

Na simulação a ser realizada, há dois eventos importantes:
? Um cliente chega à agência e entra na fila.
? Um guichê é liberado, alguém sai da fila e o utiliza.

Em cada instante de tempo, qualquer combinação desses eventos pode ocorrer (ou mesmo
nenhum deles).

Terminou o expediente?
O término do expediente será indicado pelo cronômetro, que marcará o tempo em segundos.
O período de atendimento da agência é de 6 horas, o que corresponde a 21600 segundos.
O expediente termina após este tempo decorrido.

Chegou um cliente?
Para que a simulação seja o mais próximo da realidade, será adotado um valor aleatório
para simular a chegada do cliente.
A cada segundo decorrido, será chamada uma função aleatória que sorteia um valor entre 0
e 29. Caso o número sorteado seja o número 0, isso indica que o cliente chegou. Caso
contrário, o cliente não chegou.

Cliente entra na fila
Um cliente será representado pelo horário em que ele entrou na fila. Logo, inserir um cliente
na fila equivale a simplesmente inserir nela o valor corrente do cronômetro.
Inicia a transação

Quando um guichê é liberado e um cliente se dirige a ele, é necessário saber por quanto
tempo ele ficará ocupado. Esse tempo depende da transação realizada pelo cliente. As
transações realizadas são aleatórias.

Para saber qual será a transação, um número aleatório entre 0 e 2 é gerado. Caso seja
gerado o valor 0, a transação será um saque, caso seja gerado o valor 1, a transação será
um depósito, e caso seja gerado o valor 2, a transação será um pagamento.
Finalização do expediente

Ao final do expediente, caso ainda haja clientes na fila, eles devem ser atendidos.
Quando o expediente tiver terminado e não houver mais clientes na fila, as seguintes
informações devem ser impressas:

? Número total de clientes atendidos.
? Número de clientes que fizeram saque, depósito e pagamento.
? Tempo médio de espera na fila.
? Tempo extra de expediente.

Eu vou cobrar por isso!rs

E

leo_mf:

Obrigado.
Isto eu já sabia.
Mas por exemplo:

public int metodo(int param){ final int x = param; return x; }
O que acontece com x quando duas ou mais threads entra no método?

Final em variáveis locais é diferente do static final em variáveis de instância.
Neste caso, o final serve apenas para indicar que, depois da primeira atribuição, o valor não será alterado.
Como uma variável local fica no stack (não no heap) e como cada thread tem seu stack, então duas variáveis final locais com o mesmo nome não são a mesma coisa.

L

Obrigado, entanglement

Era mais ou menos o que eu imaginava.

Criado 7 de maio de 2012
Ultima resposta 7 de mai. de 2012
Respostas 9
Participantes 2