condition的应用-三个线程不间断轮流打印1~3

123 阅读1分钟

代码实现

@Slf4j
public class Test {
    /**
     * 实现互斥的锁
      */
    private static Lock lock = new ReentrantLock();
    /**
     * 三个线程等待的条件变量
     */
    private static Condition[] conditions = new Condition[]{lock.newCondition(), lock.newCondition(), lock.newCondition()};

    /**
     * 此刻应该运行的线程号
     * volatile保证内存可见性
     */
    private  volatile int state = 1;

    /**
     * 线程运行的代码块,传入num代表线程号
     * @param num
     */
    private void run(int num){
        // 下一个运行的线程号
        int next = num%3 + 1;
        while (true){
            lock.lock();
            try{
                // 不满足条件,进入等待队列
                while(num != state){
                    conditions[num-1].await();
                }
                // 打印数字
                System.out.println(num);
                // 修改state为next
                this.state = next;
                // 唤醒下一个线程
                conditions[next-1].signalAll();
            }catch (Exception ex){
                ex.printStackTrace();
            }finally {
                lock.unlock();
            }
        }
    }

    public static void main(String[] args) {
        Test test = new Test();
        for(int i=1;i<4;i++){
            // lambda表达式中的外部变量需要是最终变量
            final int j = i;
            new Thread(()->{test.run(j);}).start();
        }
    }
}

image.png