• 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

  • 相关阅读:
    了解 NoSQL 的必读资料
    关于什么时候用assert(断言)的思考
    这次见到了一些大侠
    NetBeans 时事通讯(刊号 # 87 Jan 12, 2010)
    动态链接库dll,静态链接库lib, 导入库lib
    新女性十得 写得了代码,查得出异常
    记录系统乱谈
    新女性十得 写得了代码,查得出异常
    fullpage.js禁止滚动
    RunningMapReduceExampleTFIDF hadoopclusternet This document describes how to run the TFIDF MapReduce example against ascii books. This project is for those who wants to experiment hadoop as a skunkworks in a small cluster (110 nodes) Google Pro
  • 原文地址:https://www.cnblogs.com/ssskkk/p/12658606.html
Copyright © 2020-2023  润新知