Como posso interromper uma declaração sincronizada em Java?
-
21-09-2019 - |
Pergunta
Eu tenho dois threads que desejam sinconizar no mesmo objeto. THEAD A
precisa ser capaz de interromper o tópico B
Se uma certa condição foi cumprida. Aqui está um pseudo-código do que os dois threads fazem/devem fazer.
UMA:
public void run()
{
while(true)
{
//Do stuff
synchronized(shared)
{
//Do more stuff
if(condition)
{
B.interrupt();
}
}
}
}
B:
public void run()
{
while(true)
{
try
{
//Do stuff
synchronized(shared)
{
//Do more stuff
}
}
catch(InterruptedException e)
{
continue;
}
}
}
Aqui está a situação que não posso resolver:
- Fio
A
Pega o recurso compartilhado e faz algumas coisas. - Enquanto isso, tópico
B
atinge o bloco sincronizado e aguardaA
para liberar seu recurso compartilhado. - Fio
A
, enquanto fazia coisas, percebi que o thread B não deveria ter o recurso compartilhado e tenta interromper o tópicoB
. Mas threadB
já superou os pontos em que umInterruptedException
poderia ser jogado.
Minha pergunta é: existe alguma maneira de interromper um tópico enquanto está esperando para ser synchronized
Em algo?
Solução
Para esse tipo de coisa, você deve usar as classes em java.util.concurrent.locks
- Eles têm muito mais recursos, incluindo bloqueios interrompíveis.
Editar: Se você não pode usar essas classes, olhe para a resposta de JKFF - seus requisitos podem ser atendidos com o wait()
/notify()
Mechnismo, mas é fácil introduzir bugs sutis.
Outras dicas
Na verdade, você deve usar as fechaduras ou implementar suas coisas com o Object.wait()
, Object.notify()
e Object.notifyAll()
Métodos (os bloqueios são realmente implementados com eles). Não se esqueça de lidar com os chamados 'despertadores espúrios' (wait()
pode retornar mesmo se ninguém ligou notify()
ou notifyAll()
, então sempre deve ser chamado em um loop que verifique se a condição que você está esperando é satisfeita).
Não mas Reentrantlock.lockInterruptível ()
se comporta de maneira semelhante ao primitivo monitorenter
instrução e pode ser interrompido.