Sychronized与Lock的区别
Sychronized与Lock的区别
1、构成
- Sychronized 是关键字,属于jvm层面
- 底层是通过monitor对象来完成(monitorenter、monitorexit),wait、notify等方法也依赖monitor对象,只有在同步块或方法中才能调用
- Lock是具体的类,属于API层面
2、使用方法
- Sychronized 不需要用户手动释放锁,执行完代码后自动释放
- ReentrantLock 需要用户手动释放锁,没有释放的话可能会导致死锁。
3、等待是否可中断
- Sychronized 不可中断,除非抛出异常或者正常运行完成。
- ReentrantLock 可中断,设置超时方法1、tryLock(long timeout, TimeUnit unit ) 2、LockInterruptibly()放代码块中,调用
interrupt
可中断4、加锁是否公平
- Sychronized 非公平锁
- ReentrantLock 两者都可以,默认非公平锁。
5、锁绑定多个条件 Condition
- Sychronized 没有
- ReentrantLock 用来实现分组唤醒需要唤醒的线程,可以精确唤醒,而不是像 Sychronized 一样随机唤醒一个,或者全部唤醒。
Condition
是什么?
使用 Condition 精准通知唤醒某个线程
import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class ConditionExample02 { public static void main(String[] args) { Data3 data3 = new Data3(); new Thread(()->{ for (int i = 0; i < 3; i++) { data3.printA(); } },"A").start(); new Thread(()->{ for (int i = 0; i < 3; i++) { data3.printB(); } },"B").start(); new Thread(()->{ for (int i = 0; i < 3; i++) { data3.printC(); } },"C").start(); } } class Data3{ private Lock lock = new ReentrantLock(); private Condition condition1 = lock.newCondition(); private Condition condition2 = lock.newCondition(); private Condition condition3 = lock.newCondition(); private int num = 1; // 1A 2B 3C public void printA(){ lock.lock(); try { // 业务代码 判断 -> 执行 -> 通知 while (num != 1){ //当别的线程来的时候,判断是否num是1,不是1就阻塞在这。 condition1.await(); } System.out.println(Thread.currentThread().getName()+"=> A "); num = 2; condition2.signal(); } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } } public void printB(){ lock.lock(); try { // 业务代码 判断 -> 执行 -> 通知 while (num != 2){ condition2.await(); } System.out.println(Thread.currentThread().getName()+"=> B "); num = 3; condition3.signal(); } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } } public void printC(){ lock.lock(); try { // 业务代码 判断 -> 执行 -> 通知 while (num != 3){ condition3.await(); } System.out.println(Thread.currentThread().getName()+"=> C "); num = 1; condition1.signal(); } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } } }输出:
A=> A B=> B C=> C A=> A B=> B C=> C A=> A B=> B C=> C