如何在Java中中断同步语句?

7
我有两个线程想要在同一个对象上同步。线程A需要在满足某个条件时能够中断线程B。以下是这两个线程应该做的一些伪代码。

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

这是我无法解决的情况:
  • 线程 A 占用了共享资源并执行一些操作。
  • 同时,线程 B 到达同步块,并等待 A 释放其共享资源。
  • 线程 A 在执行操作时意识到线程 B 不应该拥有共享资源,并尝试中断线程 B。但是线程 B 已经超过了可能抛出 InterruptedException 的点。
我的问题是,是否有办法在一个线程等待对某个东西进行同步时中断它?
3个回答

6

对于这种情况,你应该使用java.util.concurrent.locks中的类-它们具有更多的功能,包括可中断锁。

编辑:如果您无法使用那些类,请查看jkff的答案-您的要求可以通过wait()/notify()机制来实现,但很容易引入微妙的错误。


1
我担心那可能是解决方案:我正在使用 Java 的子集,它默认没有这些类。它们是纯 Java 吗(如果是的话,我可以包含它们),还是需要本地库(不可行)? - Eric
这是纯Java,引入自Java 1.5。 - Valentin Rocher
@Eric,什么子集?是j2me吗? - finnw
@Valentin:我不会对此百分之百确定。这可能适用于锁,但是java.util.concurrent.atomic类绝对使用本地代码(尽管它们的规范可以以纯Java实现得不那么高效,但JDK源代码使用本地调用)。 - Michael Borgwardt
3
我使用的是LeJOS NXJ,它是用于乐高Mindstorms NXT微控制器的Java语言。 - Eric
1
如果有帮助的话,这里是一个针对没有java.util.concurrent的JVM的后移版本:http://backport-jsr166.sourceforge.net/index.php(但我不知道它是否适用于你的JVM)。 - Valentin Rocher

3

确实,你应该使用锁或者使用 Object.wait()Object.notify()Object.notifyAll() 方法来实现你的代码(锁实际上就是用它们实现的)。不要忘记处理所谓的“虚假唤醒”(即使没有人调用 notify()notifyAll()wait() 也可能返回,因此它应该始终在检查等待条件是否满足的循环中调用)。


1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接