Condition

Lock.Condition可以实现唤醒一部分线程(针对某种操作的线程)。
如果特定资源只有生产者和消费者两种线程操作,则Condition并没有多大意义。produce和consume之间相互切换,直接用wait和nofity即可。

但如果有超过两种以上的操作对应不同线程,则Condition的多路等待特性就会非常有意义。

假定有一个资源类,有三个方法m1, m2, m3, 这三个方法都是要将从1到99写入一个List. 现在要求用三个线程按固定顺序轮流写入1-99. 线程A写入1,线程B写入2,线程C写3......线程A写入97,线程B写入98,线程C写入99,然后结束。

class Resource {

    private Lock lock = new ReentrantLock();
    private Condition c1 = lock.newCondition();
    private Condition c2 = lock.newCondition();
    private Condition c3 = lock.newCondition();

    private volatile int turn = 1;

    private List data = new ArrayList<>();
    private volatile int i = 0;

    private void add(int i) {
        System.out.println(Thread.currentThread().getName() + " add: " + i);
        data.add(i);
    }

    public void m1() throws InterruptedException {
        lock.lock();
        try {
            while (i < 98) {
                while (turn != 1) {
                    c1.await();
                }
                if (i < 97)
                    add(++i);
                turn = 2;
                c2.signal();
            }
        } finally {
            lock.unlock();
        }
    }

    public void m2() throws InterruptedException {
        lock.lock();
        try {
            while (i < 99) {
                while (turn != 2) {
                    c2.await();
                }
                if (i < 98)
                    add(++i);
                turn = 3;
                c3.signal();
            }
        } finally {
            lock.unlock();
        }
    }

    public void m3() throws InterruptedException {
        lock.lock();
        try {
            while (i < 100) {
                while (turn != 3) {
                    c3.await();
                }
                if (i == 99) break;
                add(++i);

                turn = 1;
                c1.signal();
            }
        } finally {
            lock.unlock();
        }
    }
}

这个类中,三个方法分别对应三个线程的操作。

以下是测试类:

public class Main {
    public static void main(String[] args) {
        Resource r = new Resource();
        Thread a = new Thread(() -> {
            try {
                r.m1();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        Thread b = new Thread(() -> {
            try {
                r.m2();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        Thread c = new Thread(() -> {
            try {
                r.m3();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });


        a.start();
        b.start();
        c.start();

    }


}

输出: 可以看到三个线程轮流写入1-99.

Thread-0 add: 1
Thread-1 add: 2
Thread-2 add: 3
Thread-0 add: 4
Thread-1 add: 5
Thread-2 add: 6
Thread-0 add: 7
Thread-1 add: 8
Thread-2 add: 9
Thread-0 add: 10
Thread-1 add: 11
Thread-2 add: 12
Thread-0 add: 13
Thread-1 add: 14
Thread-2 add: 15
Thread-0 add: 16
Thread-1 add: 17
Thread-2 add: 18
Thread-0 add: 19
Thread-1 add: 20
Thread-2 add: 21
Thread-0 add: 22
Thread-1 add: 23
Thread-2 add: 24
Thread-0 add: 25
Thread-1 add: 26
Thread-2 add: 27
Thread-0 add: 28
Thread-1 add: 29
Thread-2 add: 30
Thread-0 add: 31
Thread-1 add: 32
Thread-2 add: 33
Thread-0 add: 34
Thread-1 add: 35
Thread-2 add: 36
Thread-0 add: 37
Thread-1 add: 38
Thread-2 add: 39
Thread-0 add: 40
Thread-1 add: 41
Thread-2 add: 42
Thread-0 add: 43
Thread-1 add: 44
Thread-2 add: 45
Thread-0 add: 46
Thread-1 add: 47
Thread-2 add: 48
Thread-0 add: 49
Thread-1 add: 50
Thread-2 add: 51
Thread-0 add: 52
Thread-1 add: 53
Thread-2 add: 54
Thread-0 add: 55
Thread-1 add: 56
Thread-2 add: 57
Thread-0 add: 58
Thread-1 add: 59
Thread-2 add: 60
Thread-0 add: 61
Thread-1 add: 62
Thread-2 add: 63
Thread-0 add: 64
Thread-1 add: 65
Thread-2 add: 66
Thread-0 add: 67
Thread-1 add: 68
Thread-2 add: 69
Thread-0 add: 70
Thread-1 add: 71
Thread-2 add: 72
Thread-0 add: 73
Thread-1 add: 74
Thread-2 add: 75
Thread-0 add: 76
Thread-1 add: 77
Thread-2 add: 78
Thread-0 add: 79
Thread-1 add: 80
Thread-2 add: 81
Thread-0 add: 82
Thread-1 add: 83
Thread-2 add: 84
Thread-0 add: 85
Thread-1 add: 86
Thread-2 add: 87
Thread-0 add: 88
Thread-1 add: 89
Thread-2 add: 90
Thread-0 add: 91
Thread-1 add: 92
Thread-2 add: 93
Thread-0 add: 94
Thread-1 add: 95
Thread-2 add: 96
Thread-0 add: 97
Thread-1 add: 98
Thread-2 add: 99

你可能感兴趣的:(Condition)