synchronized:Java提供的内置锁机制,Java中的每个对象都可以用作一个实现同步的锁(内置锁或者监视器Monitor),线程在进入同步代码块之前需要或者这把锁,在退出同步代码块会释放锁。而synchronized这种内置锁实际上是互斥的,即每把锁最多只能由一个线程持有。
Lock接口:Lock接口提供了与synchronized相似的同步功能,和synchronized(隐式的获取和释放锁,主要体现在线程进入同步代码块之前需要获取锁退出同步代码块需要释放锁)不同的是,Lock在使用的时候是显示的获取和释放锁。虽然Lock接口缺少了synchronized隐式获取释放锁的便捷性,但是对于锁的操作具有更强的可操作性、可控制性以及提供可中断操作和超时获取锁等机制。
下面我们来分别介绍synchronized和lock之间的代码区别:
synchronized有两种写法,一种是直接修饰方法,一种是利用代码块:
例如public synchronized void MyThread(){
}
第二种
synchronized{
//填入可能出现线程安全问题的代码
}
代码展示:
这是代码块↑
这是直接修饰方法↓
可以看到代码可以很简单,但是直接修饰方法的效率会比较低,因为并不是整个方法都是需要锁住的,这样会限制程序的运行速度,第二种代码块则好一点,把可能出现线程安全问题的代码写入代码块中,这样比直接修饰方法的效率会高不少。
但是使用synchronized关键字并不太好,因为synchronized太重了(系统级
别的),执行效率并不高,这样我们就有另一种加锁的方式:
lock进行加锁:
Lock接口的使用:
jdk5.0时候,jdk提供了Lock接口,为了是改善synchronized重量级锁,而设计的轻量级的锁
lock() // 加锁
unlock() // 解锁
注意:
Lock加锁后,一定要保证能够解锁,否则有可能形成死锁。
具体我们来看具体如何使用:
可见代码所示↑