zoukankan      html  css  js  c++  java
  • 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();
    就算这个世道烂成一堆粪坑,那也不是你吃屎的理由
  • 相关阅读:
    Anagram
    HDU 1205 吃糖果(鸽巢原理)
    Codeforces 1243D 0-1 MST(补图的连通图数量)
    Codeforces 1243C Tile Painting(素数)
    Codeforces 1243B2 Character Swap (Hard Version)
    Codeforces 1243B1 Character Swap (Easy Version)
    Codeforces 1243A Maximum Square
    Codeforces 1272E Nearest Opposite Parity(BFS)
    Codeforces 1272D Remove One Element
    Codeforces 1272C Yet Another Broken Keyboard
  • 原文地址:https://www.cnblogs.com/whalesea/p/12977766.html
Copyright © 2011-2022 走看看