java 使用两个线程打印序列时死锁
java deadlock while printing sequence using two threads
我尝试使用两个线程交替打印奇数和偶数。但是程序进入了僵局。我不明白为什么它会进入僵局。在调试模式下,程序的行为有所不同。它打印 1 2 然后死锁。此行为是意外的。
预期输出
1
2
3
4
odd thread ends here
even thread ends here
main thread ends here
当前输出
1
2
3
4
odd thread ends here
(Deadlock)
这是java代码
public class PrintSequence {
public static void main(String[] args) {
EvenOddPrinter printer = new EvenOddPrinter(false, 1, 4);
Thread odd = new Thread(new Runnable() {
@Override
public void run() {
printer.printOdd();
}
});
Thread even = new Thread(new Runnable() {
@Override
public void run() {
printer.printEven();
}
});
odd.start();
even.start();
try {
odd.join();
System.out.println("odd thread ends here");
even.join();
System.out.println("even thread ends here");
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("main thread ends here");
}
}
class EvenOddPrinter {
private boolean isEven;
private int index;
private int maxNumber;
public EvenOddPrinter(boolean isEven, int index, int maxNumber) {
super();
this.isEven = isEven;
this.index = index;
this.maxNumber = maxNumber;
}
public synchronized void printOdd () {
while(index < maxNumber) {
if(!isEven) {
System.out.println(index);
index++;
isEven = true;
notify();
}
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public synchronized void printEven() {
while(index <= maxNumber) {
if(isEven) {
System.out.println(index);
index++;
isEven = false;
notify();
}
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
有人可以帮我解决这个问题吗?
打印完最后一个偶数后,偶数线程释放锁。并且奇数线程在没有通知偶数线程的情况下退出该方法。从而陷入僵局。
public synchronized void printEven() {
while(index <= maxNumber) {
...
}
notify(); // add notify here
}
public synchronized void printOdd() {
while(index <= maxNumber) {
...
}
notify(); // add notify here
}
当奇数完成时,它永远不会通知偶数线程。所以这样做。
public synchronized void printOdd () {
while(index < maxNumber) {
if(!isEven) {
System.out.println(index);
index++;
isEven = true;
notify();
}
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
notify(); // add a notify here
}
我尝试使用两个线程交替打印奇数和偶数。但是程序进入了僵局。我不明白为什么它会进入僵局。在调试模式下,程序的行为有所不同。它打印 1 2 然后死锁。此行为是意外的。
预期输出
1
2
3
4
odd thread ends here
even thread ends here
main thread ends here
当前输出
1
2
3
4
odd thread ends here
(Deadlock)
这是java代码
public class PrintSequence {
public static void main(String[] args) {
EvenOddPrinter printer = new EvenOddPrinter(false, 1, 4);
Thread odd = new Thread(new Runnable() {
@Override
public void run() {
printer.printOdd();
}
});
Thread even = new Thread(new Runnable() {
@Override
public void run() {
printer.printEven();
}
});
odd.start();
even.start();
try {
odd.join();
System.out.println("odd thread ends here");
even.join();
System.out.println("even thread ends here");
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("main thread ends here");
}
}
class EvenOddPrinter {
private boolean isEven;
private int index;
private int maxNumber;
public EvenOddPrinter(boolean isEven, int index, int maxNumber) {
super();
this.isEven = isEven;
this.index = index;
this.maxNumber = maxNumber;
}
public synchronized void printOdd () {
while(index < maxNumber) {
if(!isEven) {
System.out.println(index);
index++;
isEven = true;
notify();
}
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public synchronized void printEven() {
while(index <= maxNumber) {
if(isEven) {
System.out.println(index);
index++;
isEven = false;
notify();
}
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
有人可以帮我解决这个问题吗?
打印完最后一个偶数后,偶数线程释放锁。并且奇数线程在没有通知偶数线程的情况下退出该方法。从而陷入僵局。
public synchronized void printEven() {
while(index <= maxNumber) {
...
}
notify(); // add notify here
}
public synchronized void printOdd() {
while(index <= maxNumber) {
...
}
notify(); // add notify here
}
当奇数完成时,它永远不会通知偶数线程。所以这样做。
public synchronized void printOdd () {
while(index < maxNumber) {
if(!isEven) {
System.out.println(index);
index++;
isEven = true;
notify();
}
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
notify(); // add a notify here
}