我想按顺序打印我的奇数偶数1 2 3 4 5 6.我认为首先在奇数线程中通知调用应该解除阻塞偶数线程的wait()以打印下一个偶数,但事实并非如此。它只打印“1”
class T1 extends Thread {
private String[] s1;
private boolean flag;
public T1(String[] args, boolean flag) {
this.flag = flag;
this.s1 = args;
}
public synchronized void run() {
for (int i = 0; i < s1.length; i++) {
if(flag)
{
try {
wait();
} catch (InterruptedException e) {
System.out.println("exception");
}
}
System.out.println(s1[i]);
notify();
flag = true;
}
}
}
public class TestThread {
public static void main(String[] args) {
String[] s1 = { "1", "3", "5" };
String[] s2 = { "2", "4", "6" };
Runnable odd = new T1(s1,false);
Runnable even = new T1(s2,true);
new Thread(even,"even-thread ").start();
new Thread(odd,"odd-thread ").start();
}
}
答案 0 :(得分:3)
正如其他人指出的那样,两个线程使用不同的监视器,他们应该使用共享对象作为监视器。
然而,即使修复也无法解决所有问题。因为它是我也看到错过信号的机会。 (当另一个线程没有等待时,一个线程可以调用notify)。
总而言之,您不会考虑应该用于wait-notify的一些准则。
来自实践中的Java并发:
使用条件等待(
Object.wait
或Condition.await
)时:
- 始终有一个条件谓词 - 对象状态的一些测试,必须在继续之前保持;
- 始终在调用
wait
之前测试条件谓词,并在从wait
返回后再次测试;- 始终在循环中调用
wait
;- 确保构成条件谓词的状态变量由与条件队列关联的锁保护;
- 调用
wait
,notify
或notifyAll
时,保持与条件队列关联的锁定;和- 检查条件谓词后但在采取行动之前不要释放锁定。
答案 1 :(得分:2)
你的线程正在通知自己,而不是通知另一个线程。
您可以通过在其监视器上同步后通知另一个线程来解决此问题。但是,对于共享wait()
上的notify()
和Object
会更好。
答案 2 :(得分:0)
您可能需要这样的代码:
class MyThread extends Thread {
private Object object;
private String[] s1;
public MyThread(String[] args, Object object) {
this.object = object;
this.s1 = args;
}
public void run() {
synchronized (object) {
for (int i = 0; i < s1.length; i++) {
System.out.println(s1[i]);
object.notifyAll();
if (i == s1.length - 1) return;
try {
object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
public class TestThread {
private static Object object = new Object();
public static void main(String[] args) {
String[] s1 = { "1", "3", "5" };
String[] s2 = { "2", "4", "6" };
Thread odd = new MyThread(s1, object);
odd.start();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
Thread even = new MyThread(s2, object);
even.start();
}
}
输出是:
1
2
3
4
5
6