zoukankan      html  css  js  c++  java
  • ReentrantLock的Condition使用问题

    这几天在网上看到了一个面试经常会问到的题目: 3个线程依次打印数字。我就用ReentrantLock+Condition写了一个,代码如下:

    /**
     * @auther panfei
     * @date 2018/2/8
     */
    public class ConditionTest implements Runnable {
        private final static ReentrantLock lock = new ReentrantLock();
        private final static Condition condition = lock.newCondition();
        private static int count = 0;
        private int privilege;
        private final static int THREADNUM = 3;
    
        public ConditionTest(int privilege) {
            this.privilege = privilege;
        }
    
        @Override
        public void run() {
            lock.lock();
            try {
    
                while (count <= 75) {
                    System.out.println(Thread.currentThread().getName() + " count: "+ count);
                    if (count % THREADNUM != privilege) {
                        condition.await();
                    } else {
                        System.out.println("Thread " + Thread.currentThread().getName() + " print :" + count++)
                        condition.signal();
                    }
                }
            } catch (Exception ex) {
                ex.printStackTrace();
            } finally {
                lock.unlock();
            }
        }
    
        public static void main(String[] args) {
            new Thread(new ConditionTest(0)).start();
            new Thread(new ConditionTest(1)).start();
            new Thread(new ConditionTest(2)).start();
        }
    }

    跑了一下,能够正常运行,输出结果:

    Thread Thread-0 print :0

    Thread Thread-1 print :1

    Thread Thread-2 print :2

    ……

    但是多运行几次就出现问题了:出现一个很奇怪的现象,整个进程会卡死,什么!!卡死~

    问题就出在 condition.wait();看下面一个运行日志:

    Thread-2 count: 0
    Thread-1 count: 0
    Thread-0 count: 0
    Thread Thread-0 print :0
    Thread-0 count: 1
    Thread-2 count: 1

    3个线程运行的流程大致如下:

    线程2进入 -> 线程2wait –> 线程1进入 –> 线程1等待 –> 线程0进入

    -> 线程0运行print –> 线程0 signal() ->唤醒线程2-> 线程2 wait ->线程0wait 这个时候3个线程都处于wait状态。

    问题原因:signal()只会从等待队列里唤醒一个线程,如果这个线程不能继续signal就会出现问题。

    解决的办法:

    • condition.wait() 改为condition.waitNanos(200); 提供线程等待一定时间退出;
    • condition.signal()改为condition.signalAll();唤醒所有线程
  • 相关阅读:
    地区列表
    storyboard
    快捷键2
    关于本地缓存
    深入浅出Cocoa之消息
    ARC和Non-ARC下的单例模式
    runloop原理介绍
    ARC内存管理机制详解
    解决UITableViewCell separator左侧不贴边
    UICollectionView的使用
  • 原文地址:https://www.cnblogs.com/felixpan/p/8478246.html
Copyright © 2011-2022 走看看