Lock 和 Synchronized区别

1.synchronized是关键字,是JVM层面的,lock是java类(接口)
2.synchronized不能够判断是否获取锁的状态,lock可以判断是否获取到锁
3.synchronized(隐式锁)可以自动释放锁(①:执行完同步代码时释放锁 ②:代码出现异常释放锁),lock(显示锁)需要手动在finally中释放锁(否则容易造成线程死锁)
4.synchronized修饰的线程A和线程B(同一个锁对象),当线程A在使用时,线程B等待,当线程A阻塞时,线程B一直等待,lock锁不一定会一直等待,如果在设置的超时时间内,尝试获取不到锁,线程可以不用等待就结束
5.Lock锁绑定多个条件 ConditionSynchronized 没有ReentrantLock用来实现分组唤醒需要唤醒的线程们, 可以精确唤醒, 而不是像 Synchronized 要么随机唤醒一个线程要么唤醒全部线程
6.synchronized锁适合同步少量代码,lock锁适合同步大量代码
7.使用上的区别:synchronized可以修饰普通方法(锁是当前实例对象),可以修饰静态方法(锁是当前实例的CLASS对象),可以修饰代码块(锁是括号中的实例对象),lock用来同步代码块,需要显示的调用lock()和unlock()方法来加锁和解锁
8.Synchronized采用的CPU悲观锁机制,Lock 只是一个顶层抽象接口,并没有实现,也没有规定是乐观锁还是悲观锁实现规则。而 ReentrantLock 作为 Lock 的一种实现,是悲观锁,https://blog.csdn.net/qq_35688140/article/details/101223701
ReentrantReadWriteLock 的提供了一种乐观锁的实现。
具体验证可以看看这个问题:https://ask.csdn.net/questions/774015
9.Synchronized是可重入,不可中断,非公平的,lock是可重入,可判断,公平的(也可以是非公平的)

【Synchronized不可中断,除非抛出异常或者正常运行完成 ReentrantLock可中断,使用interrupt方法】
【Synchronized 不可中断, 除非抛出异常或者正常运行完成
ReentrantLock 可中断, 1、设置超时方法 tryLock(long timeout, TimeUnit unit) 2、lockInterruptibly 放代码块中, 调用 interrupt 方法可中断】

public class SyncInterrupt {
    
    
    private static final Object o1 = new Object();

    public static void main(String[] args) throws InterruptedException {
    
    

        Thread thread1 = new Thread(() -> {
    
    
            System.out.println("t1 enter");
            synchronized (o1) {
    
    
                try {
    
    
                    System.out.println("start lock t1");
                    Thread.sleep(20000);
                    System.out.println("end lock t1");
                } catch (InterruptedException e) {
    
    
                    System.out.println("t1 interruptedException");
                    e.printStackTrace();
                }
            }
        });

        Thread thread2 = new Thread(() -> {
    
    
            System.out.println("t2 enter");
            synchronized (o1) {
    
    
                try {
    
    
                    System.out.println("start lock t2");
                    Thread.sleep(1000);
                    System.out.println("end lock t2");
                } catch (InterruptedException e) {
    
    
                    System.out.println("t2 interruptedException");
                    e.printStackTrace();
                }
            }
        });

        thread1.start();
        thread2.start();

        // 主线程休眠一下,让t1,t2线程百分百已经启动,避免线程交替导致测试结果混淆
        Thread.sleep(1000);
        // 中断t2线程的执行
        thread2.interrupt();
        System.out.println("t2 interrupt...");

    }
}

在这里插入图片描述

public class Lockinterrupt {
    
    
    private static final Lock lock = new ReentrantLock();

    public static void main(String[] args) throws InterruptedException {
    
    
        
        Thread thread1 = new Thread(() -> {
    
    
            System.out.println("t1 enter");
           // synchronized (o1) {
    
    
            lock.tryLock();
                try {
    
    
                    System.out.println("start lock t1");
                    Thread.sleep(20000);
                    System.out.println("end lock t1");
                } catch (InterruptedException e) {
    
    
                    System.out.println("t1 interruptedException");
                    e.printStackTrace();
                }finally {
    
    
                    lock.unlock();
                }
          //  }
        });

        Thread thread2 = new Thread(() -> {
    
    
            System.out.println("t2 enter");
          //  synchronized (o1) {
    
    
            lock.tryLock();
                try {
    
    
                    System.out.println("start lock t2");
                    //设置成3000秒,保证   thread2.interrupt();执行
                    Thread.sleep(3000);
                    System.out.println("end lock t2");
                } catch (InterruptedException e) {
    
    
                    System.out.println("t2 interruptedException");
                    e.printStackTrace();
                }finally {
    
    
                    lock.unlock();
                }
          //  }
        });


        thread1.start();
        thread2.start();

        // 主线程休眠一下,让t1,t2线程百分百已经启动,避免线程交替导致测试结果混淆
        Thread.sleep(1000);
        // 中断t2线程的执行
        thread2.interrupt();
        System.out.println("t2 interrupt...");
    }
}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/loveyour_1314/article/details/106600286