Skip to content

sychronized结合wait和notifyAll

java
public class Main {

    private static final Object lock = new Object();
    private static final LongAdder adder = new LongAdder();
    private static final String[] msg = {"AAA", "BBB", "CCC"};

    public static void main(String[] args) {
        // 提交所有打印线程
        for (int index = 0; index < msg.length; index++) {
            PrintTask task = new PrintTask(index);
            new Thread(task).start();
        }
    }

    public static class PrintTask implements Runnable {

        private final Integer index;

        public PrintTask(Integer index) {
            this.index = index;
        }

        @Override
        public void run() {
            // 死循环打印内容
            while (true) {
                synchronized (lock) {
                    try {
                        // 注意使用while而不是if
                        while (adder.longValue() % msg.length != index) {
                            lock.wait();
                        }
                        // 全局步长加1
                        adder.increment();
                        System.out.println(msg[index]);
                        TimeUnit.SECONDS.sleep(1);
                        // 唤醒所有在lock上阻塞的线程
                        lock.notifyAll();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
}

condition结合await和signalAll

java
public class Main {
    private static final ReentrantLock lock = new ReentrantLock();
    private static final Condition condition = lock.newCondition();

    private static final LongAdder adder = new LongAdder();
    private static final String[] msg = {"AAA", "BBB", "CCC"};

    public static void main(String[] args) {
        for (int index = 0; index < msg.length; index++) {
            PrintTask task = new PrintTask(index);
            new Thread(task).start();
        }
    }

    public static class PrintTask implements Runnable {

        private final Integer index;

        public PrintTask(Integer index) {
            this.index = index;
        }

        @Override
        public void run() {
            // 死循环
            while (true) {
                try {
                    lock.lockInterruptibly();
                    // 注意使用while而不是if
                    while (adder.longValue() % msg.length != index) {
                        condition.await();
                    }
                    // 全局步长加1
                    adder.increment();
                    System.out.println(msg[index]);
                    TimeUnit.SECONDS.sleep(1);
                    // 唤醒所有在condition上阻塞的线程
                    condition.signalAll();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }
            }
        }
    }
}

LockSupport结合park和unpark

java
public class Main {
    private static final String[] msg = {"AAA", "BBB", "CCC"};

    public static void main(String[] args) {
        PrintTask[] tasks = new PrintTask[msg.length];
        // 构建类似循环链表
        for (int index = msg.length - 1; index >= 0; index--) {
            tasks[index] = new PrintTask(index);
            if (index == msg.length - 1) continue;
            PrintTask nextTask = tasks[index + 1];
            tasks[index].setNextTask(nextTask);
        }
        tasks[msg.length - 1].setNextTask(tasks[0]);
        // 启动所有打印线程
        for (PrintTask task : tasks) {
            task.start();
        }
        // 唤醒第一个线程,发生链式作用
        LockSupport.unpark(tasks[0]);
    }

    public static class PrintTask extends Thread {

        private Integer index;
        private Thread nextTask;

        public PrintTask(Integer index) {
            this.index = index;
        }

        public void setNextTask(Thread nextTask) {
            this.nextTask = nextTask;
        }

        @Override
        public void run() {
            // 死循环
            while (true) {
                try {
                    // 阻塞当前线程
                    LockSupport.park();
                    System.out.println(msg[index]);
                    TimeUnit.SECONDS.sleep(1);
                    // 唤醒下一个阻塞的线程
                    LockSupport.unpark(nextTask);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

基于 MIT 许可发布