作为一名程序员,在求职面试时,不知道你在求职面试时常会遇到关于线程的问题。
张工是一名java程序员,3年多工作经验,有次到一家互联网公司面试软件开发工程师岗位,面试官就问了他这样一个问题。
synchronized与Lock有什么区别?
张工回答得不是很理想,面试官就说,你都工作3年多了,怎么连synchronize和Lock区别都没掌握。
听面试官这么一说,张工顿时不好意思,感觉这次面试估计要黄了。
对于这个问题,我在面试时就曾遇到过,当时回答也不是很理想,今天简单梳理下synchronized与Lock两者之间有什么区别。
我们知道,synchronized与Lock都是锁,synchronized是java中的一个关键字,也就是说是Java语言内置的特性,那么为什么会出现Lock 锁呢。两者之间有什么区别呢。
对于synchronized相信你并不陌生,我们时常会看到有一段代码块被synchronized修饰了,当一个线程获取了对应的锁,并执行该代码块时,其他线程便只能一直等待,等待获取锁的线程释放锁。
这里获取锁的线程释放锁会出现下面这两种情况:
获取锁的线程执行完了该代码块,然后线程释放对锁的占有权;
线程执行发生异常,此时JVM会让线程自动释放锁。
在这释放锁的过程中,要是获取锁的线程由于要等待IO被阻塞了,但是又没有及时释放锁,那么其他线程只能一直等待,这样就显得很被动,对程序执行效率有很大的影响,用户体验会很差。
这时候Lock就派上用场了,Lock可以不让等待的线程一直无期限地等待下去,比如在一定的时间就能够做到响应中断。
另外,从代码层看,Lock是一个接口
public interface Lock {
void lock();
void lockInterruptibly() throws InterruptedException;
boolean tryLock();
boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
void unlock();
Condition newCondition();
}
其中lock()、tryLock()、tryLock(long time, TimeUnit unit)和lockInterruptibly()方法是用来获取锁的。unLock()方法是用来释放锁的。
简单来说,Lock和synchronized有什么区别:
Lock是一个接口,而synchronized是Java中的关键字;
synchronized在发生异常时,会自动释放线程占有的锁,因此不会导致死锁现象发生;而Lock在发生异常时,如果没有主动通过unLock()去释放锁,则很可能造成死锁现象,需要注意的是,在使用Lock时需要在finally块中释放锁;
Lock可以让等待锁的线程响应中断,synchronized不行,使用synchronized时,等待的线程会一直等待下去,不能够响应中断;
通过Lock可以知道有没有成功获取锁,synchronized不行。
值得一提的是,Lock有ReadWriteLock支持并发读。
读写锁将对一个资源的访问分成了两个锁,一个ReadLock读锁和一个WriteLock写锁。正因为有了读写锁,Lock才做到了多个线程之间的读操作不会发生冲突。
上面只是对synchronized与Lock两者区别简单的对比,面试时,面试官问这样的问题,synchronized与Lock有什么区别,我想主要是考察求职者对线程并发基础能力的掌握。
在实际应用中,线程以及线程安全性是非常重要,对于这部分内容理解不够深入,而又需要用到生产项目中,遇到问题时很难定位到问题,容易造成损失。
对于一些常见的知识点,面试前建议多复习下。
由于笔者知识及水平有限,文中错漏之处在所难免,如有不足之处,欢迎交流。