考察点:考察求职者对对于并发基础能力的掌握,在实际应用中,线程以及线程的安全性非常重要和常见的功能。对这部分功能如果理解不够深刻,很容易造成生产级别的故障。
普通人:
Lock是J.U.C包里面提供的一个锁,synchronized是Java里边的一个同步关键字,都可以实现这个多线程的一个线程并发的情况下的安全性问题,然后Lock相对比较灵活点,synchronized没那么灵活。
高手:
这个问题我从四个方面来回答
(1)功能:Lock和synchronized都是Java中去用来解决线程安全问题的一个工具。
(2)特性:synchronized是Java中的同步关键字,而Lock是J.U.C包里提供的一个接口,而这个接口它有很多的实现类。其中就包括ReentrantLock这样一个重入锁的实现,其次synchronized可以通过两种实现方式,去控制锁的力度。
像这样synchronized修饰位置
- 把synchronized关键字修饰在方法层面
- 修饰在代码块上
并且我们可以通过synchronized加锁对象的生命周期来控制锁的作用范围,比如锁对象是静态对象或者是类对象,那么这个锁就是属于全局锁,如果这个锁对象是普通实例对象,那么这个锁的范围取决于这个实例的生命周期;
Lock中的锁的粒度是通过它里面提供的lock()方法和unlock方法来决定的,
像这样包裹在两个方法之间的代码,是能够保证线程安全的,而锁的作用域取决于lock实例的生命周期。
Lock比synchronized的灵活性更高
- Lock可以自主的决定什么时候加锁,什么时候释放锁,只需要调用lock()方法和unlock()方法就可以了,同时lock还提供了非阻塞的竞争锁的方法,叫trylock()方法,这个方法可以通过返回true/false来告诉当前线程是否已经有其他线程正在使用锁;
- 而synchronized由于是关键字,所以它无法去实现非阻塞竞争锁的方法,另外synchronized锁的释放是被动的,就是当synchronized的同步代码块执行结束以后或者代码块出现异常的时候才会释放;
- 最后Lock提供了公平锁和非公平锁的机制,公平锁是指线程竞争锁资源的时候,如果已经有其他线程正在排队,或者等待锁释放,那么当前竞争锁的线程是无法区插队的,而非公平锁就是不管是否有线程在排队等待锁,它都会去尝试一次竞争一次锁,synchronized只提供了一种非公平锁的实现。
(3)性能:Lock和synchronized在性能方面相差不大,在实现上会有一定的区别,synchronized引入了偏向锁,轻量级锁,重量级锁以及锁升级的机制来实现锁的优化;而Lock中则用了自旋锁的方式去实现性能优化,以上就是我对这个问题的理解。