多线程 - 甚至奇数序列

san*_*hat 2 java multithreading producer-consumer

我试图解决多线程问题,并且我很难了解其行为.

问题是: 有2个线程同时消耗偶数奇数.我必须介绍它们之间的线程通信,以便在自然顺序中具有"消耗".

这是我的代码

public class EvenOddDemo {

    public static void main(String[] args) {
        Number n = new Number();
        EvenThread et = new EvenThread(n);
        OddThread ot = new OddThread(n);
        et.start();
        ot.start();
    }

}

class EvenThread extends Thread {

    private Number number;

    public EvenThread(Number number) {
        this.number = number;
    }

    @Override
    public void run() {
        for(int i=0; i<5; i++) {
            System.out.println(number.getEven());
        }
    }


}

class OddThread extends Thread {

    private Number number;

    public OddThread(Number number) {
        this.number = number;
    }

    @Override
    public void run() {
        for(int i=0; i<5; i++) {
            System.out.println(number.getOdd());
        }
    }


}

class Number {

    private int currentEven = 0;

    private int currentOdd = 1;

    private volatile String last = "odd";

    public synchronized int getEven() {
        if("even".equals(last)) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        int i = currentEven;
        last = "even";
        currentEven +=2;
        notify();
        return i;
    }

    public synchronized int getOdd() {
        if("odd".equals(last)) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        int i = currentOdd;
        last = "odd";
        currentOdd +=2;
        notify();
        return i;
    }
}
Run Code Online (Sandbox Code Playgroud)

而输出是

0
2
1
3
4
5
7
6
8
9
Run Code Online (Sandbox Code Playgroud)

但是当我调试代码时,它会以正确的顺序打印数字.因此,我无法弄清楚我错过了什么.请帮我.在此先感谢您的时间.

fge*_*fge 5

据我所知,没有什么可以防止这种情况发生,解释为什么在输出2之前显示1:

OddThread     EvenThread
----------    ----------
gets odd
              gets even
              prints even
prints odd
Run Code Online (Sandbox Code Playgroud)

因此,锁需要围绕整个序列"get/print".

你会注意到你的输出中你永远不会"分开两个数字".