• ReentrantLock


    一、将ReentrantLock和synchronized进行比较

    1、synchronized和ReentrantLock都是独占锁,不同的是synchronized加锁和解锁过程自动进行;ReentrantLock需手动加锁解锁。

    2、synchronized和ReentrantLock都可重入,不同的是synchronized自动进行,不必担心最后是否释放锁;但是ReentrantLock手动进行,加锁和解锁的次数需要完全一样。

    可重入演示:

                synchronized (this){
                    System.out.println(Thread.currentThread().getName()+" :synchronized代码块start.....");
                    System.out.println(Thread.currentThread().getName()+" :synchronized代码块sleep.....");
                    Thread.sleep(2000);
                    System.out.println(Thread.currentThread().getName()+" :synchronized代码块voer!!!");
                    synchronized (this){
                        System.out.println("重入");
                    }
                }

    3、相应中断:synchronized不可相应中断;ReentrantLock可以。

    二、ReentrantLock的特性

    1、简单演示

    public class ReentrantLockRunnable implements Runnable{
        private ReentrantLock lock = new ReentrantLock(true);
      
        @Override
        public void run() {
            try{
                while (true){
                    lock.lock();
                    
                    System.out.println(Thread.currentThread().getName()+"ReenTrant 已加锁");
                    Thread.sleep(2000);
                    System.out.println(Thread.currentThread().getName()+"sleep.....");
                }
    
            }catch (InterruptedException e){
                System.out.println("中断");
                e.printStackTrace();
            }finally {
                    lock.unlock();
                System.out.println(Thread.currentThread().getName()+"ReenTrant 锁已释放!!!!");
            }
    
    
        }
    }
    
    
    import lombok.SneakyThrows;
    
    public class ReentrantLockDemo {
    
        @SneakyThrows
        public static void main(String[] args){
            Runnable lock = new ReentrantLockRunnable();
            Thread thread1 = new Thread(lock);
            Thread thread2 = new Thread(lock);
    
            thread1.start();
            thread2.start();
        }
    
    }

    结果:

    Thread-0ReenTrant 已加锁
    Thread-0sleep.....
    Thread-0ReenTrant 锁已释放!!!!
    Thread-1ReenTrant 已加锁
    Thread-1sleep.....
    Thread-1ReenTrant 锁已释放!!!!

    2、公平锁

    线程获取锁的顺序按照调用lock方法的顺序,慎用!

    private ReentrantLock lock = new ReentrantLock(true);

    只需要添加true参数即可;不添加或者false参数既是不公平锁,随机获取。

    3、响应中断

    import java.util.concurrent.locks.ReentrantLock;
    
    public class ReentrantLockRunnable implements Runnable{
        private ReentrantLock lock = new ReentrantLock(true);
        private static int count = 0;
        @Override
        public void run() {
            try{
                while (true){
                    lock.lock();
                    count++;
                    System.out.println(Thread.currentThread().getName()+"ReenTrant 已加锁");
                    Thread.sleep(2000);
                    System.out.println(Thread.currentThread().getName()+"sleep.....");
                }
    
            }catch (InterruptedException e){
                System.out.println("中断");
    //            e.printStackTrace();
            }finally {
                for(int i=0;i<count;i++){
                    lock.unlock();
                }
    
                System.out.println(Thread.currentThread().getName()+"ReenTrant 锁已释放!!!!");
            }
    
    
        }
    }
    
    
    import lombok.SneakyThrows;
    
    public class ReentrantLockDemo {
    
        @SneakyThrows
        public static void main(String[] args){
            Runnable lock = new ReentrantLockRunnable();
            Thread thread1 = new Thread(lock);
            Thread thread2 = new Thread(lock);
    
            thread1.start();
            thread2.start();
            Thread.sleep(5000);
            thread1.interrupt();
        }
    
    }

    结果:

    Thread-0ReenTrant 已加锁
    Thread-0sleep.....
    Thread-0ReenTrant 已加锁
    Thread-0sleep.....
    Thread-0ReenTrant 已加锁
    中断
    Thread-0ReenTrant 锁已释放!!!!
    Thread-1ReenTrant 已加锁
    Thread-1sleep.....
    Thread-1ReenTrant 已加锁
    Thread-1sleep.....
    Thread-1ReenTrant 已加锁
    Thread-1sleep.....
    Thread-1ReenTrant 已加锁
    Thread-1sleep.....
    。。。。。持续运行

    上述代码中加锁几次释放几次,现在把finally中的代码修改:

    finally {
                
                lock.unlock();
                System.out.println(Thread.currentThread().getName()+"ReenTrant 锁已释放!!!!");
            }

    结果:

    Thread-0ReenTrant 已加锁
    Thread-0sleep.....
    Thread-0ReenTrant 已加锁
    Thread-0sleep.....
    Thread-0ReenTrant 已加锁
    中断
    Thread-0ReenTrant 锁已释放!!!!

    Thread-1线程无法进入继续运行,因为锁没有完全释放。加了三次锁,只释放了两次。

    5、限时等待

    使用tryLock带替lock,设置等待时间,如果取得锁则返回true,如果没有取得则返回false。无参默认不等待,直接返回结果。

    import java.util.concurrent.TimeUnit;
    import java.util.concurrent.locks.ReentrantLock;
    
    public class ReentrantLockDome2 implements Runnable{
        private ReentrantLock lock = new ReentrantLock();
    
        @Override
        public void run() {
    
            try{
                if (lock.tryLock(1, TimeUnit.SECONDS)){
                    System.out.println(Thread.currentThread().getName()+": 已加锁!");
                    
                    System.out.println(Thread.currentThread().getName()+": sleep....");
                    TimeUnit.SECONDS.sleep(5);
                }else{
                    System.out.println(Thread.currentThread().getName()+": come here!");
                    System.out.println(Thread.currentThread().getName()+": over!");
                }
            }catch (InterruptedException e){
                System.out.println(Thread.currentThread().getName()+":中断");
            }finally {
                if(lock.isHeldByCurrentThread()){//此锁是否由当前线程持有
                    lock.unlock();
                    System.out.println(Thread.currentThread().getName()+": 释放锁!");
                }
    
            }
    
    
        }
    
        public static void main(String[] args){
            ReentrantLockDome2 reentrantLockDome2 = new ReentrantLockDome2();
            Thread thread1 = new Thread(reentrantLockDome2);
            Thread thread2 = new Thread(reentrantLockDome2);
    
            thread1.start();
            thread2.start();
    
        }
    }

    结果:

    Thread-0: 已加锁!
    Thread-0: sleep....
    Thread-1: come here!
    Thread-1: over!
    Thread-0: 释放锁!
    lock.lock();
    就算这个世道烂成一堆粪坑,那也不是你吃屎的理由
  • 相关阅读:
    Xamarin.Forms项目无法添加服务引用
    Xamarin Android长度单位区别
    21IC菜农研究的HotWC3超级CRC运算器
    Delphi天气预报查询
    超外差接收机工作原理?
    ARM汇编指令的特点和速查表
    序列号的设计,不重复的实现一机一码
    iOS第一个简单APP
    GetEnvironmentVariable 获取常用系统变量(转)
    Delphi版的Base64转换函数(修改版)
  • 原文地址:https://www.cnblogs.com/whalesea/p/12977766.html
Copyright © 2020-2023  润新知