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 
全部评论

相关推荐

点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务