zoukankan      html  css  js  c++  java
  • 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线程重新申请锁,而后该持锁线程会释放锁)。

  • 相关阅读:
    电商 JQuery 抓取联系人信息 复制的代发兔
    Linux-Centos下安装工具用来解压压缩
    Linux远程连接及上传文件
    虚拟机-Linux-Centos8.1 与宿主主机ping互通
    虚拟机-Linux-Centos8.1联网
    数字量输入模块和模拟量输入模块的区别是什么?
    串口转以太网模块设备介绍和使用说明
    以太网模块是什么,以太网模块的功能和特点
    4G DTU连接阿里云说明手册
    react07
  • 原文地址:https://www.cnblogs.com/lyhero11/p/12219160.html
Copyright © 2011-2022 走看看