美文网首页Java多线程Java
多个线程顺序打印问题

多个线程顺序打印问题

作者: 伊凡的一天 | 来源:发表于2018-07-25 10:17 被阅读137次

    三个线程分别打印A,B,C,要求这三个线程一起运行,打印n次,输出形如“ABCABCABC....”的字符串。

    1. 解法一:使用Lock

    public class PrintABCUsingLock {
        private int times;
        private int state;
        private Lock lock = new ReentrantLock();
    
        public PrintABCUsingLock(int times) {
            this.times = times;
        }
    
        public static void main(String[] args) {
            PrintABCUsingLock printABC = new PrintABCUsingLock(10);
            new Thread(printABC::printA).start();
            new Thread(printABC::printB).start();
            new Thread(printABC::printC).start();
        }
    
        public void printA() {
            print("A", 0);
        }
    
        public void printB() {
            print("B", 1);
        }
    
        public void printC() {
            print("C", 2);
        }
    
        private void print(String name, int targetState) {
            for (int i = 0; i < times;) {
                lock.lock();
                if (state % 3 == targetState) {
                    state++;
                    i++;
                    System.out.print(name);
                }
                lock.unlock();
            }
        }
    }
    

    2. 解法二:使用wait/notify

    public class PrintABCUsingWaitNotify {
        private int times;
        private int state;
        private Object objectA = new Object();
        private Object objectB = new Object();
        private Object objectC = new Object();
    
        public PrintABCUsingWaitNotify(int times) {
            this.times = times;
        }
    
        public static void main(String[] args) {
            PrintABCUsingWaitNotify printABC = new PrintABCUsingWaitNotify(10);
            new Thread(printABC::printA).start();
            new Thread(printABC::printB).start();
            new Thread(printABC::printC).start();
        }
    
        public void printA() {
            try {
                print("A", 0, objectA, objectB);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    
        public void printB() {
            try {
                print("B", 1, objectB, objectC);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    
        public void printC() {
            try {
                print("C", 2, objectC, objectA);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    
        private void print(String name, int targetState, Object current, Object next)
                throws InterruptedException {
            for (int i = 0; i < times;) {
                synchronized (current) {
                    while (state % 3 != targetState) {
                        current.wait();
                    }
                    state++;
                    i++;
                    System.out.print(name);
                    synchronized (next) {
                        next.notify();
                    }
    
                }
            }
        }
    }
    

    解法三:使用Lock/Condition

    public class PrintABCUsingLockCondition {
        private int times;
        private int state;
        private Lock lock = new ReentrantLock();
        private Condition conditionA = lock.newCondition();
        private Condition conditionB = lock.newCondition();
        private Condition conditionC = lock.newCondition();
    
        public PrintABCUsingLockCondition(int times) {
            this.times = times;
        }
    
        public static void main(String[] args) {
            PrintABCUsingLockCondition printABC = new PrintABCUsingLockCondition(10);
            new Thread(printABC::printA).start();
            new Thread(printABC::printB).start();
            new Thread(printABC::printC).start();
        }
    
        public void printA() {
            print("A", 0, conditionA, conditionB);
        }
    
        public void printB() {
            print("B", 1, conditionB, conditionC);
        }
    
        public void printC() {
            print("C", 2, conditionC, conditionA);
        }
    
        private void print(String name, int targetState, Condition current,
                Condition next) {
            for (int i = 0; i < times;) {
                lock.lock();
                try {
                    while (state % 3 != targetState) {
                        current.await();
                    }
                    state++;
                    i++;
                    System.out.print(name);
                    next.signal();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }
            }
        }
    }
    

    解法四:使用Semaphore

    public class PrintABCUsingSemaphore {
        private int times;
        private Semaphore semaphoreA = new Semaphore(1);
        private Semaphore semaphoreB = new Semaphore(0);
        private Semaphore semaphoreC = new Semaphore(0);
    
        public PrintABCUsingSemaphore(int times) {
            this.times = times;
        }
    
        public static void main(String[] args) {
            PrintABCUsingSemaphore printABC = new PrintABCUsingSemaphore(10);
            new Thread(printABC::printA).start();
            new Thread(printABC::printB).start();
            new Thread(printABC::printC).start();
        }
    
        public void printA() {
            try {
                print("A", semaphoreA, semaphoreB);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    
        public void printB() {
            try {
                print("B", semaphoreB, semaphoreC);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    
        public void printC() {
            try {
                print("C", semaphoreC, semaphoreA);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    
        private void print(String name, Semaphore current, Semaphore next)
                throws InterruptedException {
            for (int i = 0; i < times; i++) {
                current.acquire();
                System.out.print(name);
                next.release();
            }
        }
    }
    

    相关文章

      网友评论

        本文标题:多个线程顺序打印问题

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