线程协作初步

问题引入

用三个线程分别打印三次A, B, C, 要求保证其打印的顺序, 即打印出ABCABCABC

没错又是一道面试题, 后来学习了一些线程知识, 就突然想到这道题

解决方案

ReentrantLock绑定多个Condition来实现线程协作

代码

public class ABC {
    static Lock lock = new ReentrantLock();
    static Condition ca = lock.newCondition();
    static Condition cb = lock.newCondition();
    static Condition cc = lock.newCondition();

    public static void main(String[] args) {
        A a = new A();
        B b = new B();
        C c = new C();
        
        ExecutorService executor = Executors.newCachedThreadPool();
        executor.execute(a);
        executor.execute(b);
        executor.execute(c);
        
        lock.lock();
        try {
            ca.signal();
        } finally {
            lock.unlock();
        }
        
        executor.shutdown();
    }

    static class A implements Runnable {
        @Override
        public void run() {
            for (int i = 0; i < 3; i++) {
                lock.lock();
                try {
                    ca.await();
                    System.out.print("A");
                    cb.signal();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }
            }
        }
    }
    
    static class B implements Runnable {
        @Override
        public void run() {
            for (int i = 0; i < 3; i++) {
                lock.lock();
                try {
                    cb.await();
                    System.out.print("B");
                    cc.signal();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }
            }
        }
    }
    
    static class C implements Runnable {
        @Override
        public void run() {
            for (int i = 0; i < 3; i++) {
                lock.lock();
                try {
                    cc.await();
                    System.out.print("C");
                    ca.signal();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }
            }
        }
    }
}

试着运行了一下, 完美解决

新问题

本以为完美解决了, 整个人沉浸在获得新知识的愉悦中, 情不自禁的多运行了几次

结果发现并不是每次都能完美运行, 偶尔会出现死锁...

随着学习的深入, 以后再来解决这个问题

如有大佬随手指点迷津, 愚不胜感激 😃

posted @ 2019-05-08 21:06  树是树非树  阅读(136)  评论(1编辑  收藏  举报