zoukankan      html  css  js  c++  java
  • ReentrantLock和synchronized的区别

    概述

    Synchronized

    优点:实现简单,语义清晰,便于JVM堆栈跟踪,加锁解锁过程由JVM自动控制,提供了多种优化方案,使用更广泛

    缺点:悲观的排他锁,不能进行高级功能

    Lock

    优点:可定时的、可轮询的与可中断的锁获取操作,提供了读写锁、公平锁和非公平锁  

    缺点:需手动释放锁unlock,不适合JVM进行堆栈跟踪

    相同点

    都是可重复锁

    ReentrantLock用于替代synchronized 但是ReentrantLock比较灵活

    https://www.cnblogs.com/jiangds/p/6476293.html

    应用层面

    相比synchronized,ReentrantLock增加了一些高级功能主要有以下三个:等待可中断、可实现公平锁、以及锁可以绑定多个条件

    1)使用reentrantlock可以进行“尝试锁定”tryLock,这样无法锁定,或者在指定时间内无法锁定,线程可以决定是否继续等待

          返回值是Boolean类型 表示在指定时间内 是否拿到锁

        void m2() {
            
            boolean locked = false;
            
            try {
                locked = lock.tryLock(5, TimeUnit.SECONDS);
                System.out.println("m2 ..." + locked);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                if(locked) lock.unlock();
            }
            
        }

    2)等待可中断

    使用ReentrantLock还可以调用lockInterruptibly方法,可以对线程interrupt方法做出响应,
    在一个线程等待锁的过程中,可以被打断

    Lock lock = new ReentrantLock();       
            
            Thread t1 = new Thread(()->{
                try {
                    lock.lock();
                    System.out.println("t1 start");
                    TimeUnit.SECONDS.sleep(Integer.MAX_VALUE);
                    System.out.println("t1 end");
                } catch (InterruptedException e) {
                    System.out.println("interrupted!");
                } finally {
                    lock.unlock();
                }
            });
            t1.start();
            
            Thread t2 = new Thread(()->{
                try {
                    //lock.lock();
                    lock.lockInterruptibly(); //可以对interrupt()方法做出响应
                    System.out.println("t2 start");
                    TimeUnit.SECONDS.sleep(5);
                    System.out.println("t2 end");
                } catch (InterruptedException e) {
                    System.out.println("interrupted!");
                } finally {
                    lock.unlock();
                }
            });
            t2.start();
            
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            t2.interrupt(); //打断线程2的等待

    3)可实现公平锁

     非公平锁是线程直接抢锁。公平锁会检查等待队列里有没有在等待的线程,如果有它会排在等待队列后面等待

    public class ReentrantLock5 extends Thread {
    
        private static ReentrantLock lock=new ReentrantLock(true); //参数为true表示为公平锁,请对比输出结果
        public void run() {
            for(int i=0; i<100; i++) {
                lock.lock();
                try{
                    System.out.println(Thread.currentThread().getName()+"获得锁");
                }finally{
                    lock.unlock();
                }
            }
        }
        public static void main(String[] args) {
            ReentrantLock5 rl=new ReentrantLock5();
            Thread th1=new Thread(rl);
            Thread th2=new Thread(rl);
            th1.start();
            th2.start();
        }
    }

    Thread-1获得锁
    Thread-2获得锁
    Thread-1获得锁
    Thread-2获得锁
    Thread-1获得锁......

    4)绑定多个条件

    参考Lock Condition实现生产者和消费者

    https://www.cnblogs.com/ssskkk/p/12659224.html#_label0

    实现原理不同

    https://www.cnblogs.com/ssskkk/p/12814323.html

  • 相关阅读:
    [Aaronyang] 写给自己的WPF4.5 笔记[2依赖属性]
    [Aaronyang] 写给自己的WPF4.5 笔记[1布局]
    [AaronYang]C#人爱学不学[7]
    [AaronYang]C#人爱学不学[6]
    [AaronYang]C#人爱学不学[5]
    [AaronYang]C#人爱学不学[4]
    [AaronYang]C#人爱学不学[3]
    [AaronYang]C#人爱学不学[2]
    [AaronYang]C#人爱学不学[1]
    [aaronyang原创] Mssql 一张表3列的sql面试题,看你sql学的怎么样
  • 原文地址:https://www.cnblogs.com/ssskkk/p/12658606.html
Copyright © 2011-2022 走看看