我正在尝试使用2个线程。 1个线程只打印奇数,另一个线程只打印偶数,它必须是一个替代操作。
例如:
Thread1 1
Thread2 2
Thread1 3
Thread2 4
and so on..
以下是程序,请告诉我出错的地方,因为即使thread2正在通知它,thread1也没有退出等待状态..
public class ThreadInteraction {
public static void main(String[] args) {
new ThreadInteraction().test();
}
private void test() {
ThreadA ta = new ThreadA();
Thread t = new Thread(ta);
t.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
for(int i=2;i<=50;){
System.out.println("Thread2 "+i);
synchronized (t) {
try {
t.notify();
t.wait();
} catch (Exception e) {
e.printStackTrace();
}
}
i=i+2;
}
}
}
class ThreadA implements Runnable{
@Override
public void run() {
for(int i=1;i<50;){
System.out.println("Thread1 "+i);
synchronized (this) {
try {
notify();
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
i=i+2;
}
}
}
答案 0 :(得分:2)
问题是,在一种情况下,您正在锁定Thread t
[synchronized(t)],而在其他情况下,您正在锁定TheadA
对象本身[synchronized(this)]。
如果你想让线程相互通信,那么两者都应该锁定同一个对象,然后wait notify将按预期工作。
编辑:
您的程序中还有另一个问题,您没有使用任何变量来协调2个线程。所以你可能会看到这样的输出2,1,4,3 ......等等。点是线程交替工作但不按顺序工作。 所以你应该在2个线程之间共享一个应该递增的变量。 第二个问题是你没有处理虚假的唤醒调用[阅读一些关于此的文档],你应该总是等待一段时间内调用。
答案 1 :(得分:0)
根据Lokesh提供的答案修改我的代码
public class ThreadInteraction {
public static void main(String[] args) {
new ThreadInteraction().test();
}
private void test() {
ThreadA ta = new ThreadA();
Thread t = new Thread(ta);
t.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
for(int i=2;i<=50;){
System.out.println("Thread2 "+i);
synchronized (ta) {
try {
ta.notify();
ta.wait();
} catch (Exception e) {
e.printStackTrace();
}
}
i=i+2;
}
}
}
class ThreadA implements Runnable{
@Override
public void run() {
for(int i=1;i<50;){
System.out.println("Thread1 "+i);
synchronized (this) {
try {
notify();
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
i=i+2;
}
}
}
答案 2 :(得分:0)
你真的混淆了线程和锁。我建议您创建一个且只有一个用于锁定的对象,因为您似乎并不清楚自己锁定了什么。
如果您通知()并且没有任何内容正在侦听,则信号将丢失。但是,wait()可以虚假地唤醒。
因此,notify()应该伴随状态更改,而wait()应该在循环中检查更改。