Question

J'ai deux fils qui veulent synchonize sur le même objet. Thead A doit être en mesure d'interrompre la discussion B si une certaine condition a été fullfilled. Voici quelques pseudo-code de ce que les deux threads ne / devraient faire.

A:

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;
        }
    }
}

Voici la situation que je ne peux pas résoudre:

  • Discussion A saisit la ressource partagée et fait des choses.
  • Pendant ce temps, le fil B atteint le bloc synchronisé, et attend pour A de libérer sa ressource partagée.
  • Discussion A, tout en faisant des choses, réalisé que le thread B ne devrait pas avoir la ressource partagée, et tente d'interrompre la discussion B. Mais cette discussion B a déjà dépassé les points où pourrait être jeté un InterruptedException.

Ma question est, est-il un moyen d'interrompre un fil alors qu'il est en attente d'être synchronized sur quelque chose?

Était-ce utile?

La solution

Pour ce genre de chose, vous devez utiliser les classes dans java.util.concurrent.locks -. ils ont beaucoup plus de fonctionnalités, y compris les serrures interrompues

Edit:. Si vous ne pouvez pas utiliser ces classes, puis regardez la réponse de jkff - vos besoins peuvent être satisfaits avec le mechnism wait() / de notify(), mais il est facile d'introduire des bugs subtils

Autres conseils

En effet, vous devez utiliser les serrures ou mettre en œuvre vos trucs avec les Object.wait(), Object.notify() et méthodes Object.notifyAll() (serrures sont effectivement mises en œuvre avec eux). Ne pas oublier de traiter les soi-disant « wakeups parasites » (wait() peut revenir même si Noone appelé notify() ou notifyAll(), il devrait donc toujours être appelée dans une boucle qui vérifie que la condition que vous attendez est satisfaite).

Non, mais ReentrantLock.lockInterruptibly() se comporte comme l'instruction monitorenter primitive et peut être interrompue.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top