她和他之间为何难解难分,深夜显式锁和隐式锁竟然干出这样的事!

2022-07-25,

什么是显式锁和隐式锁,区别是什么?

- 所谓的显式锁和隐式锁,主要是指的synchronized关键字和ReentrantLock类。 他们的区别是:

1 底层不同

  • synchronized是Java中的关键字,是JVM层面的锁
  • ReentranLock是JDK5以后出现的具体的类。其使用的是lock来调用API

2 使用方式不同

  • 显式锁和隐式锁最大的不同在于,我们使用的时候要不要手动去获取锁和释放锁
//例如:锁对象
Lock l = new ReetrantLock();
//手动开启锁
l.lock();
//手动关闭锁
l.unlock();
//隐式锁的两种实现方式在下面哦

3 是否是公平锁

synchronized 是非公平锁

lock创建时可以传入一个Boolean值来设置是公平锁还是非公平锁:

true:公平锁
false:非公平锁

4 是否可以中断

  • sychronized 是不可中断的,除非抛出异常或者正常运行完成lock才可以中断。

帅气的分割线,因为,下面要上隐式锁的实现方式,哈哈哈,哈哈哈哈哈哈哈哈哈,哈哈哈哈哈哈哈哈!炸天帮万岁!

我们知道,隐式锁有两种实现方式分别为:同步代码块和同步方法。
他们两个都是创建锁后自动开关锁,并且用synchronized关键字

1. 同步代码块

public class Demo6 {
    public static void main(String[] args) {
        Runnable r = new Ticket();
        //创建两个线程执行售票任务
        new Thread(r).start();
        new Thread(r).start();
    }
    //实现Runnable接口
    static class Ticket implements Runnable{
        private int count = 10;
        //创建一个用于标记的锁对象
        private Object o = new Object();
        @Override
        public void run() {//重写run任务 - 售票任务
            while (true) {
                synchronized (o) {//synchronized关键字 传入唯一的锁对象
                    if (count > 0) {
                        count--;
                        System.out.println(Thread.currentThread().getName() + 
                                           "出票成功,余票" + count);	
                    }else {
                        break;
                    }
                }
            }
        }
    }
}

输出

2. 同步方法

public class Demo7 {
    public static void main(String[] args) {
        Runnable r = new Ticket();
        new Thread(r).start();
        new Thread(r).start();
        new Thread(r).start();
    }
    static class Ticket implements Runnable{
        private int count = 10;
        @Override
        public void run() {//重写run任务
            while (true) {
                boolean falg = sale();
                if(!falg)
                    break;
            }
        }
        public synchronized boolean sale(){//加上synchronized关键字锁方法 实现排队
            if(count > 0){
                count--;
                System.out.println(Thread.currentThread().getName()+"出票成功,余票"+count);
                return true;
            }//return的是false的话就结束卖票
            return false;
        }
    }
}

输出结果如果发现每此都是Thread-0,就多试几次,因为每次0抢到了以后,去返回,再去抢,比别人更近,懒得试了。
嗯,就似嗦~被锁住的代码块,谁先抢到进行代码执行之后,那它连续抢到的几率会很大。
举一个好吃的栗子

  • 小明在商场中排队上厕所,这时,有个人,刚在厕所中出来,突然又很急,所以它只需要转身就可以继续上。

输出的完美状态是:

Thread-0出票成功,余票9
Thread-0出票成功,余票8
Thread-0出票成功,余票7
Thread-1出票成功,余票6
Thread-1出票成功,余票5
Thread-1出票成功,余票4
Thread-0出票成功,余票3
Thread-2出票成功,余票2
Thread-2出票成功,余票1
Thread-2出票成功,余票0

综合以上我们发现,不管你是同步代码块还是同步方法,是龙给我卧着,是虎,啊不是,是都要排队。溜了!

本文地址:https://blog.csdn.net/CrazyCaesar/article/details/112006976

《她和他之间为何难解难分,深夜显式锁和隐式锁竟然干出这样的事!.doc》

下载本文的Word格式文档,以方便收藏与打印。