欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-03-27 08:49:27
什么是显式锁和隐式锁,区别是什么?- 所谓的显式锁和隐式锁,主要是指的synchronized关键字和ReentrantLock类。 他们的区别是:1 底层不同synchronized是Java中的关键字,是JVM层面的锁ReentranLock是JDK5以后出现的具体的类。其使用的是lock来调用API2 使用方式不同显式锁和隐式锁最大的不同在于,我们使用的时候要不要手动去获取锁和释放锁//例如:锁对象Lock l = new ReetrantLock();//手动开...

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

- 所谓的显式锁和隐式锁,主要是指的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