Condition

作者: 俊杰的笔记 | 来源:发表于2018-04-05 19:20 被阅读7次

    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<Integer> 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

          本文链接:https://www.haomeiwen.com/subject/beydhftx.html