Java 线程等待通知
我有 3 个线程(A、B、C),但我无法让它们按照我想要的方式工作。 所有这 3 个线程共享对同一对象 - K 的引用。 我想做的是启动所有 3 个线程,然后在线程 A 到达某个状态时的某个时间点,暂停线程 B 和 C,直到 A 执行某个方法 work() ,当工作完成时,恢复B 和 C。
现在我的代码中有什么: 线程 A 引用了 B 和 C。 B和C有一个方法pause(){synchronized(K){k.wait; }} 当 A 到达某个状态时,我调用 FROM A 的 run() 方法:B.pause()、C.pause()。 现在我期待的是线程 B 和 C 将等待,直到有人发出 k.notifyAll(),但线程 A 停止了。这在java中正常吗?
代码:
class A implements Runnable {
private K k;
private B b;
private C c;
void run() {
while(something) {
//do something
b.pause();
c.pause();
// !!! here this thread will freeze and doSomething2 wont get executed.
// what i want is to pause B, C, doSomething2 to get executed and then resume B and C
//do something2
synchronized(k) {
k.notifyAll();
}
}
}
}
class B implements Runnable {
private K k;
void run() {
while(something) {
//dome something
}
}
}
public pause() {
synchronized(k) { k.wait();}
}
}
class C implements Runnable {
private K k;
void run() {
while(something) {
//dome something
}
}
}
public pause() {
synchronized(k) { k.wait();}
}
}
I have 3 threads (A, B, C) that i just can't make them work how i want them to.
ALL these 3 threads share a reference to the same object - K.
What i'm trying to do, is to start all 3 up, then at some point in time when thread A arrives in a certain state, pause threads B and C, until A executes some method work() and when work finishes, resume B and C.
Now what i have in my code:
Thread A has reference to both B and C.
B and C have a method pause() { synchronized(K) { k.wait; }}
When A arrives in that certain state, i call FROM A's run() method: B.pause(), C.pause().
Now what i'm expecting is that Threads B and C will waiT until someone makes a: k.notifyAll(), BUT instead Thread A stops. Is this normal in java ?
Code:
class A implements Runnable {
private K k;
private B b;
private C c;
void run() {
while(something) {
//do something
b.pause();
c.pause();
// !!! here this thread will freeze and doSomething2 wont get executed.
// what i want is to pause B, C, doSomething2 to get executed and then resume B and C
//do something2
synchronized(k) {
k.notifyAll();
}
}
}
}
class B implements Runnable {
private K k;
void run() {
while(something) {
//dome something
}
}
}
public pause() {
synchronized(k) { k.wait();}
}
}
class C implements Runnable {
private K k;
void run() {
while(something) {
//dome something
}
}
}
public pause() {
synchronized(k) { k.wait();}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
您可以使用 CylcicBarrier 来实现这。
You can use a CylcicBarrier to implement this.
当你调用 B.pause() 时,它是在本地线程中执行的,而不是在你调用 B 的 run 方法的线程中执行的。
Thread 类中有一些已弃用的方法可以执行此操作,但它们很危险,请参见此处:
http://download.oracle.com/javase/1.5 .0/docs/guide/misc/threadPrimitiveDeprecation.html
When you call B.pause(), it is executed in the local thread, not in the thread where you called run method of B.
There are some deprecated methods on the Thread class to do that but they are dangerous, see here:
http://download.oracle.com/javase/1.5.0/docs/guide/misc/threadPrimitiveDeprecation.html
您确定调用 b.pause() 但声明 B.sleep() 吗?
很高兴看到线程构造/启动代码。
Are you sure that you call b.pause() but declare B.sleep() ?
Would be nice to see threads construction/start code.
您知道您正在使用 3 个不同的对象(监视器)Ak、Bk、Ck 吗?
因此,当 B“暂停”时,它会在自己的监视器 (Bk) 上同步,无论如何,该监视器应该是空闲的。
您的线程不会以任何方式“通信”。
You know that you are using 3 diferent objects (monitors) A.k,B.k,C.k ?
So when B "paused" it synchronized on their own monitor (B.k) that should be free anyway.
Your threads do not "communicate" in any way.
从
A.run()
中删除对b.pause()
和c.pause()
的调用,并从它们自己的 run 方法中调用它们。Remove the calls to
b.pause()
andc.pause()
fromA.run()
and call them from their own run methods.除非我误解了你的作业,否则我认为你需要做的是学习如何中断线程。 B 和 C 是可中断线程,需要以这样的方式处理中断:在被告知可以之前它们不会恢复。它可能看起来像这样:
因此,在自己的线程中运行的对象 A 将引用其他两个线程。对象 A 将有权访问共享监视器对象,其他两个线程中的可运行对象也可以访问该对象(我将其称为“监视器”)。当 A 中断其他线程时,它们的可运行对象将在监视器上调用
wait()
。当 A 完成后,它将在监视器上调用notifyAll()
。注意,您也应该清除其他线程中的中断标志,但我将其留给您来解决 - 这很容易:)Unless I am misunderstanding your homework assignment, what I think you need to do is learn how to interrupt a thread. B and C are interruptable threads that need to handle the interrupt in such a way that they will not resume until they have been told it is OK. It could look something like this:
So object A running in its own thread will have references to two other threads. Object A will have access to a shared monitor object that the runnables in the two other threads also have access to (I called it
monitor
). When A interrupts the other threads their runnables will then callwait()
on the monitor. When A is done it will callnotifyAll()
on the monitor. NOTE you should clear the interrupt flag in the other threads too, but I leave that to you to figure out - its easy :)我通常不会在这个细节上帮助你完成家庭作业,但我认为你无论如何都使用了错误的方法,所以我认为帮助你做一些你几乎肯定不应该做的事情并没有什么坏处:)
我猜你真正想做的是无条件地在
B
和C
中的k
上调用 wait,然后始终在A 中调用 notificationAll
I don't normally help with homework in this detail, but I think you are using the wrong approach anyway, so I don't see the harm in helping you do something you almost certainly shouldn't be doing :)
I'm guessing that what you really want to do though is unconditionally call wait in on
k
inB
andC
and then always call notifyAll inA