有两个线程,一个是打印偶数,另一个打印奇数。在下面的自定义锁的帮助下,我想按顺序打印数字。问题是打印一些数字后(显示的数字是正确的顺序。)线程正在陷入僵局。我花了一个多小时仍然无法找到问题,对我来说一切似乎都很好。
public class Main{
public static void main(String[] args){
Lock lock=new Lock();
SharedData sharedData=new SharedData(lock);
Thread th1=new Thread(new EvenWriter(sharedData));
Thread th2=new Thread(new OddWriter(sharedData));
th1.start();
th2.start();
}
}
class SharedData{
Lock lock;
boolean printOdd;
SharedData(Lock lock){
this.lock=lock;
this.printOdd=true;
}
}
class OddWriter implements Runnable{
SharedData sharedData;
int num;
Lock lock;
public OddWriter(SharedData sharedData){
this.sharedData=sharedData;
this.num=1;
this.lock=sharedData.lock;
}
public void run(){
while(true){
if(sharedData.printOdd){
lock.lock();
System.out.println(num);
num=num+2;
sharedData.printOdd=false;
lock.unlock();
}
}
}
}
class EvenWriter implements Runnable{
SharedData sharedData;
int num;
Lock lock;
public EvenWriter(SharedData sharedData){
this.sharedData=sharedData;
this.num=2;
this.lock=sharedData.lock;
}
public void run(){
while(true){
if(!sharedData.printOdd){
lock.lock();
System.out.println(num);
num=num+2;
sharedData.printOdd=true;
lock.unlock();
}
}
}
}
class Lock{
private boolean locked=false;
public synchronized void lock(){
while(locked){
try{
wait();
}
catch(Exception e){
e.printStackTrace();
}
}
locked=true;
}
public synchronized void unlock(){
locked=false;
try{
notifyAll();
}
catch(Exception e){
e.printStackTrace();
}
}
}
答案 0 :(得分:0)
您需要制作printOdd
volatile
,例如
class SharedData{
Lock lock;
volatile boolean printOdd;
SharedData(Lock lock) {
this.lock=lock;
this.printOdd=true;
}
}
这是因为您在多个线程中使用printOdd
; volatile
的目的是确保所有线程都可以访问一块内存。您之前所做的是允许printOdd
仅访问OddWriter
线程,因为它是第一个访问它的线程。
答案 1 :(得分:-1)
两个线程之间共享的数据是原子的。在您的情况下,boolean printOdd
在线程之间共享,这是导致死锁的原因。
你能用吗
AtomicBoolean printOdd;