Afr*_*ius 6 java multithreading actionlistener wait
我有一个激活2个线程的应用程序,第1个启动另一个类来进行一些处理,然后启动第3个类来进行更多处理.主类中的第二个线程应该等到第三个类中的某个事件在执行其作业之前完成.怎么能实现这一目标?
我曾尝试实现一个wait/notify来共享两个线程之间的锁对象,但从技术上讲,这不会起作用,因为我找到了困难的方法.我可以在课堂之间分享锁吗?注意,第3个类的实例在第1个类中声明,并作为参数传递给第2个类.此外,我尝试在第3类中创建布尔值,告诉事件何时完成然后轮询第2个线程,直到该值为真.这有效,但不是很理想.actionListner也是解决这个问题的更好方法吗?
rsp*_*rsp 11
你遇到了什么问题?正如你所描述的那样,它应该有效.例如,您可以在第3个类上实现2个方法,这些方法保留一个标志,该标志从一个中检查,并使用实例作为锁从另一个类中设置:
boolean done = false;
public synchronized setDone() {
done = true;
this.notifyAll();
}
public synchronized waitUntilDone() {
while (!done) {
try {
this.wait();
} catch (InterruptedException ignore) {
// log.debug("interrupted: " + ignore.getMessage());
}
}
}
Run Code Online (Sandbox Code Playgroud)
(注意:从内存中键入,不使用Java编译检查)
原则上,this.在不需要等待和notifyAll之前,我发现在这种情况下包括它们更清楚.
您想使用计数信号量。条件变量用于调度监视器内的线程。这不是你想要做的。
您创建一个计数信号量并将计数设置为零
// create a counting semaphore with an initial count of zero
java.util.concurrent.Semaphore s = new java.util.concurrent.Semaphore(0);
Run Code Online (Sandbox Code Playgroud)
您将信号量传递给您的类来进行处理。完成后,它通过调用将计数增加到 1 s.release()。
要阻塞线程直到处理器完成,您可以调用s.aquire()。该调用将导致您的其他线程阻塞,直到处理器调用s.release().
这是最简单的解决方案。
顺便说一句,s.aquire()并且s.release()是线程安全的,因此您不需要使用同步关键字。线程可以共享对信号量的引用并调用其方法而无需锁定。
更新:
我将在这里回复您的评论,而不是发表新评论。
是的,在您的情况下, wait()/notify() 解决方案类似于使用信号量。要使用信号量重写 rsp 的解决方案,它看起来像:
java.util.concurrent.Semaphore s = new java.util.concurrent.Semaphore(0);
public setDone() {
s.release();
}
public waitUntilDone() {
s.aquire();
}
Run Code Online (Sandbox Code Playgroud)
它要简单得多,并且不需要不必要的锁(请注意,我从方法 decs 中删除了同步关键字。)。
条件变量(wait()/notify())和信号量之间有两个区别。
区别#1:对notify()的调用可能会丢失,对release()的调用永远不会丢失
第一个区别是,如果没有线程通过调用 wait() 进行等待,则对 notification() 的调用将会丢失。解决方法是在调用 wait() 之前检查条件。基本上,我们需要记住,notify() 是使用共享变量调用的,这样我们就不会在工作线程调用notify() 后意外地调用wait(),否则就会死锁。无论 acquire() 和 release() 的调用顺序如何,计数信号量都会起作用,因为它们在内部维护计数。
区别#2:调用 wait() 会自动释放锁,而调用 acquire() 则不会
一些背景信息会有所帮助。在您的程序中,boolean done = false;
变量是条件,但它不是条件变量。我知道术语令人困惑。条件变量是具有wait()和notify()操作的变量。Java中的每个对象都隐藏着一个条件变量和一个相应的锁。
所有条件变量都与锁相关联。您必须先获取锁,然后才能调用 wait() 和 notification() (如果不获取锁,将会出现运行时异常,请尝试一下)。一旦获得锁,调用 wait() 会自动释放锁,从而允许监视器内的另一个线程可能调用 notify()。有时,这正是您想要的,并且尝试用信号量模拟这种行为会复杂得多。
注意:我使用的是监视器的学术定义,它与监视器的 Java 定义完全不同。
| 归档时间: |
|
| 查看次数: |
15687 次 |
| 最近记录: |