java Implement Runnable未显示正确的结果
我试图对一个类使用wait()和notify()来通知等待的线程,但情况是,谁先进入同步块,谁就会等待其他线程打印一些值并通知等待的线程。但等待的线索是继续等待。我做错了什么
public class MyRunnableClass implements Runnable {
public static boolean transfer = false;
public static boolean isAnyThreadWaiting = false;
int a=10;
@Override
public void run() {
// TODO Auto-generated method stub
synchronized(this) {
System.out.println("I am Thread : "+Thread.currentThread().getName()+" and I first occuipied block");
try {
if(isAnyThreadWaiting)
MyRunnableClass.transfer=true;
if(!MyRunnableClass.transfer&&!isAnyThreadWaiting) {
System.out.println("I am Thread : "+Thread.currentThread().getName()+" and I am going to wait");
while(!MyRunnableClass.transfer) {
isAnyThreadWaiting=true;
this.wait();
}
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
for(int i=0; i<a;i++) {
System.out.println("I am Thread : "+Thread.currentThread().getName()+" Value of a is : "+i );
}
a=0;
isAnyThreadWaiting=false;
this.notify();
}
}
public static void main(String [] args) throws InterruptedException {
MyRunnableClass runnable1= new MyRunnableClass();
Thread thread1=new Thread(runnable1,"t1");
Thread thread2=new Thread(runnable1,"t2");
thread1. start();
thread2. start();
}
}
# 1 楼答案
this
在两个线程中都是相同的,因为您使用了相同的Runnable
实例^{synchronized
块的开头,另一个线程位于wait
。您需要将同步范围缩小到实际使用共享状态的位置,即仅synchronized(this)
实际引用(读取或写入)两个线程所需变量的代码# 2 楼答案
对一个线程中的静态变量所做的更改对另一个线程不可见。因此,对于这两个线程,它总是transfer==false和isAnyThreadWaiting==false
这意味着两个线程都会进入“wait()”块并永远卡在那里
因为您试图对静态变量进行同步,所以必须使用synchronized static方法
请参见此处的更多详细信息: How to synchronize a static variable among threads running different instances of a class in Java?
但更简单的解决方案是根本不使用静态变量。 在您的情况下,两个线程使用同一个对象,因此不需要将变量设置为静态:
完整的解决方案应该如下所示:
# 3 楼答案
我已经调试了你的代码并找到了原因:
请删除此代码,您将看到两个线程的输出:
另外,示例中的第二个线程实际上没有进入wait()状态
但是,由于通过第二个线程将a设置为0,第一个线程跳过了这个周期:
这就是为什么你看不到第一个线程的输出。但它并没有停留在等待()状态