ReentrantLock 条件变量简单使用记录

ReentrantLock 支持多条件变量,用于唤醒指定的部分线程。

   /**
     * 	ReentrantLock  方法,用以获取一个条件变量实例,可以理解为不满足条件的线程的暂时等待的区域。
     * 	Returns a {@link Condition} instance for use with this
     *  {@link Lock} instance.
     */
    public Condition newCondition() {
        return sync.newCondition();
    }

以下为一个条件变量使用的例子:

	private static ReentrantLock lock = new ReentrantLock();
	//条件
    private static boolean hasSmoke = false;
    private static boolean hasSnacks = false;

    public static void main(String[] args) {
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2, 5, 0, TimeUnit.MINUTES, new LinkedBlockingDeque<>());
        //烟
        Condition smoke = lock.newCondition();
        //零食
        Condition snacks = lock.newCondition();

        threadPoolExecutor.submit(() -> {
            lock.lock();
            try {
            	//while 防止虚假唤醒
            	//即没有满足该条件,执行了之后的代码,暂时这么理解
                while (!hasSmoke) {
                    try {
                        log.info(Thread.currentThread().getName() + "  没有烟,不能干...");
                        //Condition 对象调用await()方法,放弃持有的锁,进入休息区等待
                        smoke.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                log.info("来烟啦,崩一根...");
            } finally {
                lock.unlock();
            }
        });
        threadPoolExecutor.submit(() -> {
            lock.lock();
            try {
                while (!hasSnacks) {
                    try {
                        log.info(Thread.currentThread().getName() + "  零食也不让吃,不能干...");
                        snacks.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                log.info("吃饱了,干活...");
            } finally {
                lock.unlock();
            }
        });
        
        threadPoolExecutor.submit(() -> {
            lock.lock();
            try {
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                hasSmoke = true;
                log.info("送烟的来咯...");
                //调用signalAll()方法,唤醒smoke等待区的所有线程
                smoke.signalAll();
                //唤醒等待区的某一个线程
                //smoke.signal();
                hasSnacks = true;
                log.info("零食来咯...");
                snacks.signalAll();
            } finally {
                lock.unlock();
            }
        });

        threadPoolExecutor.shutdown();
    }
上一篇:pytest之.pytest_cache文件夹作用【Pytest中的cache缓存功能】


下一篇:cassandra中的ACID,与RDBMS中的事务有何不同?