三个线程按顺序循环输出ABC ABC ABC

一、Synchronized解决

import java.util.concurrent.*;

public class Test {

    public static void main(String[] args) throws Exception {
        ExecutorService pool = Executors.newFixedThreadPool(3);
        PrintTask task = new PrintTask();
        pool.execute(() -> {
            try {
                task.printA();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        pool.execute(() -> {
            try {
                task.printB();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        pool.execute(() -> {
            try {
                task.printC();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        pool.shutdown();
    }


    private static class PrintTask{
        private volatile static Integer flag = 0;

        private synchronized void printA() throws InterruptedException {
            while (true){
                if (flag == 0){
                    System.out.println(Thread.currentThread().getName() + "-----A");
                    Thread.sleep(500);
                    flag = 1;
                    notifyAll();
                }else{
                    wait();
                }
            }
        }

        private synchronized void printB() throws InterruptedException {
            while (true){
                if (flag == 1){
                    System.out.println(Thread.currentThread().getName() + "-----B");
                    Thread.sleep(500);
                    flag = 2;
                    notifyAll();
                }else{
                    wait();
                }
            }
        }

        private synchronized void printC() throws InterruptedException {
            while (true){
                if (flag == 2){
                    System.out.println(Thread.currentThread().getName() + "-----C");
                    Thread.sleep(500);
                    flag = 0;
                    notifyAll();
                }else{
                    wait();
                }
            }
        }
    }

}

输出:

二、lock解决

import java.util.concurrent.*;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class Test {

    public static void main(String[] args) throws Exception {
        ExecutorService pool = Executors.newFixedThreadPool(3);
        PrintTask task = new PrintTask();
        pool.execute(() -> {
            try {
                task.printA();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        pool.execute(() -> {
            try {
                task.printB();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        pool.execute(() -> {
            try {
                task.printC();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        pool.shutdown();
    }


    private static class PrintTask{
        private volatile static Integer flag = 0;
        private Lock lock = new ReentrantLock();
        private Condition conditionA = lock.newCondition();
        private Condition conditionB = lock.newCondition();
        private Condition conditionC = lock.newCondition();

        private void printA() throws InterruptedException {
            try {
                lock.lock();
                while (true) {
                    if (flag == 0) {
                        System.out.println(Thread.currentThread().getName() + "-----A");
                        Thread.sleep(500);
                        flag = 1;
                        conditionB.signal();
                    } else {
                        conditionA.await();
                    }
                }
            } finally {
                lock.unlock();
            }
        }

        private void printB() throws InterruptedException {
            try {
                lock.lock();
                while (true) {
                    if (flag == 1) {
                        System.out.println(Thread.currentThread().getName() + "-----B");
                        Thread.sleep(500);
                        flag = 2;
                        conditionC.signal();
                    } else {
                        conditionB.await();
                    }
                }
            } finally {
                lock.unlock();
            }
        }

        private void printC() throws InterruptedException {
            try {
                lock.lock();
                while (true) {
                    if (flag == 2) {
                        System.out.println(Thread.currentThread().getName() + "-----C");
                        Thread.sleep(500);
                        flag = 0;
                        conditionA.signal();
                    } else {
                        conditionC.await();
                    }
                }
            } finally {
                lock.unlock();
            }
        }
    }

}

输出:

三、信号量解决

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;

public class Test {

    public static void main(String[] args) throws Exception {
        ExecutorService pool = Executors.newFixedThreadPool(3);
        PrintTask task = new PrintTask();
        pool.execute(() -> {
            try {
                task.printA();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        pool.execute(() -> {
            try {
                task.printB();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        pool.execute(() -> {
            try {
                task.printC();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        pool.shutdown();
    }


    private static class PrintTask{
        private Semaphore semaphoreA = new Semaphore(1);
        private Semaphore semaphoreB = new Semaphore(0);
        private Semaphore semaphoreC = new Semaphore(0);

        private void printA() throws InterruptedException {
            while (true) {
                semaphoreA.acquire();
                System.out.println(Thread.currentThread().getName() + "-----A");
                Thread.sleep(500);
                semaphoreB.release();
            }
        }

        private void printB() throws InterruptedException {
            while (true) {
                semaphoreB.acquire();
                System.out.println(Thread.currentThread().getName() + "-----B");
                Thread.sleep(500);
                semaphoreC.release();
            }
        }

        private void printC() throws InterruptedException {
            while (true) {
                semaphoreC.acquire();
                System.out.println(Thread.currentThread().getName() + "-----C");
                Thread.sleep(500);
                semaphoreA.release();
            }
        }
    }

}

注意:多次调用release,或release(int),可以动态增加permits的个数,构造参数中的permits数量是初始值,不是最终的许可数量。

输出:

原文地址:https://www.cnblogs.com/LUA123/p/13033218.html