我有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();}
}
}
答案 0 :(得分:3)
您可以使用CylcicBarrier来实现此目的。
CyclicBarrier barrier = new CyclicBarrier();
public void run() {
new Thread(new A(barrier)).start();
new Thread(new B(barrier)).start();
barrier.await(); // Waits until all threads have called await()
// Do something
}
public void A implements Runnable {
private CyclicBarrier barrier;
public A(CyclicBarrier barrier) {
this.barrier = barrier;
}
public void run() {
barrier.await();
// Do something.
}
}
public void B implements Runnable {
private CyclicBarrier barrier;
public B(CyclicBarrier barrier) {
this.barrier = barrier;
}
public void run() {
barrier.await();
// Do something.
}
}
答案 1 :(得分:1)
当你调用B.pause()时,它在本地线程中执行,而不是在你调用B的run方法的线程中执行。 Thread类上有一些不赞成使用的方法,但是它们很危险,请看这里: http://download.oracle.com/javase/1.5.0/docs/guide/misc/threadPrimitiveDeprecation.html
答案 2 :(得分:0)
你确定你调用b.pause()但声明B.sleep()吗?
很高兴看到线程构造/开始代码。
答案 3 :(得分:0)
你知道你使用的是3个不同的对象(监视器)A.k,B.k,C.k?
所以,当B“暂停”它在他们自己的显示器(B.k)上同步,无论如何都应该是免费的。 你的主题没有以任何方式“沟通”。
答案 4 :(得分:0)
从b.pause()
移除对c.pause()
和A.run()
的来电,并使用自己的运行方式调用它们。
答案 5 :(得分:0)
除非我误解你的家庭作业,否则我认为你需要学习如何打断一个线程。 B和C是可中断的线程,需要以这样一种方式处理中断,即在被告知它没有问题之前它们不会恢复。它可能看起来像这样:
while(true)
{
try
{
Thread.sleep(100);
System.out.println("Thread is working normally...");
}
catch(InterruptedException e)
{
System.out.println("Thread has been interrupted, will wait till A is done...");
try
{
synchronized(monitor)
{
monitor.wait();
}
}
catch(InterruptedException e2)
{
// whatever...
}
}
}
因此,在自己的线程中运行的对象将引用另外两个线程。对象A可以访问共享的监视器对象,其他两个线程中的可运行对象也可以访问它(我称之为monitor
)。当A中断其他线程时,它们的runnable将在监视器上调用wait()
。 A完成后,它将在监视器上调用notifyAll()
。注意你也应该清除其他线程中的中断标志,但我把它留给你弄清楚 - 很容易:)
答案 6 :(得分:0)
我通常不会在这个细节上帮助做作业,但我认为你无论如何都在使用错误的方法,所以我没有看到帮助你做一些你几乎肯定不应该做的事情的伤害:)< / p>
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;
volatile boolean isPaused = false;
void run() {
while(something) {
if (isPaused) {
synchronized(k) { k.wait();}
isPaused = false;
}
//dome something
}
}
public pause() {
isPaused = true;
}
}
class C implements Runnable {
private K k;
volatile boolean isPaused = false;
void run() {
while(something) {
if (isPaused) {
synchronized(k) {
k.wait();
}
isPaused = false;
}
//dome something
}
}
public pause() {
isPaused = true;
}
}
我猜你真正想做的事情是无条件地在k
和B
中C
呼叫等待,然后始终在A
中呼叫notifyAll / p>