• java并发编程中的ReentrantLock(一)


    package com.wangan.logistic;
    
    import java.util.concurrent.locks.Condition;
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    
    public class WanganReentrantLockService {
        private Lock lock = new ReentrantLock();
        private Condition condition = lock.newCondition();
        
        private void await() {
            try {
                lock.lock();
                System.out.println(Thread.currentThread().getName() + "线程获得了lock");
                System.out.println(Thread.currentThread().getName() + "线程await,暂交出锁,并进入等待队列");
                condition.await();
                System.out.println(Thread.currentThread().getName() + "线程被从await唤醒,获得之前交出的锁并继续执行");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }finally {
                lock.unlock();
                System.out.println(Thread.currentThread().getName() + "线程释放了lock");
            }
        }
        
        private void signal() {
            try {
                lock.lock();
                System.out.println(Thread.currentThread().getName() + "线程获得了lock");
                condition.signal();
                System.out.println(Thread.currentThread().getName() + "线程发出signal,非公平唤醒等待队列中的其他线程");
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                lock.unlock();
                System.out.println(Thread.currentThread().getName() + "线程释放了锁");
            }
        }
        
        
        public static void main(String[] args) {
            WanganReentrantLockService service = new WanganReentrantLockService();
            new Thread(new Runnable() {
                @Override
                public void run() {
                    /*
                     * 这块可以模拟一下如果这个线程比main线程跑的慢,会发生什么
                        try {
                            Thread.sleep(5000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    */
                    service.await();
                }
            }).start();
            try {
                Thread.sleep(3000);    //防止main线程跑得比Thread-0还快
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            service.signal();
        }
    }

    控制台输出:

    Thread-0线程获得了lock
    Thread-0线程await,暂交出锁,并进入等待队列
    main线程获得了lock
    main线程发出signal,非公平唤醒等待队列中的其他线程
    main线程释放了锁
    Thread-0线程被从await唤醒,获得之前交出的锁并继续执行
    Thread-0线程释放了lock

    程序进程执行完毕,进程正常结束。

    如果把代码中注释掉的部分放开,故意让new出来的线程跑的比main线程慢的话,控制台输出:

    main线程获得了lock
    main线程发出signal,非公平唤醒等待队列中的其他线程
    main线程释放了锁
    Thread-0线程获得了lock
    Thread-0线程await,暂交出锁,并进入等待队列

    此时由于最后Thread-0线程一直处于await没有其他线程去唤醒了,程序进程会一直阻塞中。

    最后,看一下lock.newCondition()的说明:

    Condition java.util.concurrent.locks.Lock.newCondition()

    Returns a new Condition instance that is bound to this Lock instance.
    Before waiting on the condition the lock must be held by thecurrent thread.
    A call to Condition.await() will atomically release the lockbefore waiting
    and re-acquire the lock before the wait returns.

    newCondition()会返回一个与当前lock绑定的Condition实例。当前线程必须先获得lock,才能condition.await()。

    一旦调用condition.await(),当前线程会释放lock然后进入waiting(此时lock会被其他线程获得),并且在从wait返回之前会重新申请锁(持有锁的线程signal通知其他wait线程重新申请锁,而后该持锁线程会释放锁)。

  • 相关阅读:
    Hibernate系列教材 (十六)- 各类概念
    Hibernate系列教材 (十五)- 各类概念
    Hibernate系列教材 (十四)- 各类概念
    Hibernate系列教材 (十三)- 各类概念
    Hibernate系列教材 (十二)- 关系
    Hibernate系列教材 (十一)- 关系
    Hibernate系列教材 (十)- 关系
    codeforces1509 C. The Sports Festival (区间DP)
    洛谷P3194 [HNOI2008]水平可见直线(计算几何+单调栈)
    CF1265E Beautiful Mirrors (概率dp)
  • 原文地址:https://www.cnblogs.com/lyhero11/p/12219160.html
Copyright © 2020-2023  润新知