• 显示锁ReentrantLock和Condition的使用


    一、ReentrantLock
    (1)、java.util.concurrent.locks包中的ReentrantLock就是重入锁,它实现了Lock接口,Lock加锁和解锁都是显示的。ReentrantLock重入锁可以实现synchronized关键字的功能。
    主要方法:
    lock:获得锁。
    unlock:释放锁。
    (2)、java对synchronized优化之后,ReentrantLock和synchronize大的区别:
    a、锁的粒度,ReentrantLock更细,更灵活。
    b、ReentrantLock可以指定锁的公平性。synchronize只能是非公平的。
    c、ReentrantLock可以利用Condition(条件)类选择性分组唤醒线程。
    d、ReentrantLock可以中断一个正在等待获取锁的线程。lockInterruptibly()。
    (3)、典型的使用格式:

    class X {
       private final ReentrantLock lock = new ReentrantLock();
       // ...
       public void m() {
         lock.lock();  // block until condition holds
         try {
           // ... method body
         } finally {
           lock.unlock()
         }
       }
     }

    测试i++的代码:
    注意:必须在finally块中调用unlock语句释放锁,以确保即使在方法体中抛出异常(try块)锁也会释放锁。否则这个锁永远不释放。

    /**
     * @author monkjavaer
     * @date 2018/12/16 22:24
     */
    public class ReentrantLockService{
    
        private Lock lock = new ReentrantLock();
        private int count = 0;
    
        public void getCount(){
            try {
                //获得锁
                lock.lock();
                System.out.println("thread :"+Thread.currentThread().getName()+" count = "+count++);
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                //在finally块中调用unlock语句,以确保即使在方法体中抛出异常(try块)也会释放锁。
                lock.unlock();
            }
        }
    
    
        public static void main(String[] args) {
            ReentrantLockService service = new ReentrantLockService();
            for(int i=0; i<100; i++){
                new Thread("" + i){
                    @Override
                    public void run(){
                        service.getCount();
                    }
                }.start();
            }
        }
    
    }
    

    二、Condition
    (1)、Condition通过Lock对象调用newCondition()方法获得。借助Lock,Condition可以实现wait && notify同样的功能。主要方法:
    await(): 使当前线程等待
    signal():唤醒一个等待的线程
    signalAll():唤醒所有等待的线程
    (2)、在使用Condition的方法时需要先获得锁,即调用Lock对象的lock()方法,否则会抛出IllegalMonitorStateException,因为没有监视器对象。

    Condition使用实例:

    /**
     * @author monkjavaer
     * @date 2018/12/18 21:14
     */
    public class ConditionService {
        private Lock lock = new ReentrantLock();
        private Condition condition = lock.newCondition();
    
        public void awaitTest(){
            try {
                lock.lock();
                System.out.println("before await()");
                condition.await();
                System.out.println("after await()");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }finally {
                lock.unlock();
            }
        }
    
        public void signalTest(){
            try {
                lock.lock();
                System.out.println("before signal()");
                condition.signal();
                System.out.println("after signal()");
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                lock.unlock();
            }
        }
    
        public static void main(String[] args) {
            ConditionService service = new ConditionService();
            Thread thread1 = new Thread(new Runnable() {
                @Override
                public void run() {
                    service.awaitTest();
                }
            });
            thread1.start();
    
            Thread thread2 = new Thread(new Runnable() {
                @Override
                public void run() {
                    service.signalTest();
                }
            });
            thread2.start();
        }
    }
    

      

      

  • 相关阅读:
    Docker
    dcoker-componse-2
    MyBatis的基本使用
    SpringMVC实现文件上传和下载
    CF817E Choosing The Commander
    CSP 2020 游记
    COCI2014-2015 Contest#1 题目选做
    CF590D Top Secret Task
    LuoguP1937 [USACO10MAR]Barn Allocation G
    CF741C Arpa’s overnight party and Mehrdad’s silent entering
  • 原文地址:https://www.cnblogs.com/monkjavaer/p/10140658.html
Copyright © 2020-2023  润新知