【问题标题】:java deadlock while printing sequence using two threads使用两个线程打印序列时出现java死锁
【发布时间】:2020-03-29 15:27:02
【问题描述】:

我尝试使用两个线程打印奇数和偶数。但程序进入了僵局。我无法理解为什么它会陷入僵局。在调试模式下,程序的行为不同。它打印 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();
            }
        }
    }
}

有人可以帮我解决这个问题吗?

【问题讨论】:

  • 这不是死锁。死锁需要 2 个锁。这只是一个逻辑问题。你可以想办法。
  • @NathanHughes 是不是忘记发送消息(通知)某种形式的死锁(例如参见en.wikipedia.org/wiki/Deadlock 上的定义)?虽然这仍然需要两个线程相互等待。
  • @Mark:这很有趣。我从来没有听说过一个定义包括这样的丢失消息。但是是的,在这种情况下,一个线程完成,另一个挂起。

标签: java synchronization wait deadlock notify


【解决方案1】:

当奇数完成时,它永远不会通知偶数线程。就这样吧。

    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
    }   

【讨论】:

    【解决方案2】:

    打印最后一个偶数后,偶数线程释放锁。奇数线程退出该方法而不通知偶数线程。因此陷入僵局。

    public synchronized void printEven() {
    while(index <= maxNumber) {
    ...
    }
    notify(); // add notify here
    }
    
    
    public synchronized void printOdd() {
    while(index <= maxNumber) {
    ...
    }
    notify(); // add notify here
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-01
      • 1970-01-01
      • 2022-11-26
      • 1970-01-01
      • 2013-07-24
      相关资源
      最近更新 更多