método com variaveis final e threads

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!

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.

[quote=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.
[/quote]

Somente de tipos primitivos.

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

Não.

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.

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”.

[quote=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”.
[/quote]

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?

[quote=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.[/quote]

Eu vou cobrar por isso!rs

[quote=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?[/quote]

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.

Obrigado, entanglement

Era mais ou menos o que eu imaginava.