多线程学习三(synchronized和Lock)

本文介绍了Java中多线程同步的两种方式:synchronized和Lock接口,特别是从JDK1.5开始引入的Lock接口的使用。Lock提供了比synchronized更多的控制选项,如可重入性、条件变量等。通过示例展示了如何在代码中正确使用ReentrantLock,并对比了Lock和synchronized的区别,以及如何通过Condition对象实现更灵活的线程通信。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

注意:JDK1.4之前版本用同步synchronized, JDK1.5之后版本用java.util.concurrent.locks中的Lock接口。
它比synchronized有更多的操作。

1.同步代码块或同步函数的锁操作是隐式的,为了体现面向对象的思想,JDK1.5(5.0)及之后有了Lock接口,将锁单独封装
成一个对象并且提供了对锁的显示操作。

简介ReentrantLock的使用
一个可重入的互斥锁定 Lock,它具有与使用 synchronized 方法和语句所访问的隐式监视器锁定相同的一些基本行为和语
义,但功能更强大。 

ReentrantLock 将由最近成功获得锁定,并且还没有释放该锁定的线程所拥有。当锁定没有被另一个线程所拥有时,调用 
ock 的线程将成功获取该锁定并返回。如果当前线程已经拥有该锁定,此方法将立即返回。可以用 isHeldByCurrentThread() 和 getHoldCount() 方法来检查此情况是否发生。 


举例:
实践,使用 try 块来调用 lock,在之前/之后的构造中,最典型的代码如下: 

 class X {
   private final ReentrantLock lock = new ReentrantLock();
   // ...

   public void m() { 
     lock.lock();  // block until condition holds
     try {
       // ... method body
     } finally {
       lock.unlock()
     }
   }
 }
 除了实现 Lock 接口,此类还定义了 isLocked 和 getLockQueueLength 方法,以及一些相关的 protected 访问方法,

这些方法对检测和监视可能很有用。 

2.旧版本将监视器方法(wait(),notify(),notifyAll())封装到了每一个对象中,而现在将监视器方法(await (),signal(),signalAll())封装到了Condition对象中,这样可以通过Lock接口的newCondition()方法完成。

举例
 class BoundedBuffer {
   final Lock lock = new ReentrantLock();
   final Condition notFull  = lock.newCondition(); 
   final Condition notEmpty = lock.newCondition(); 

   final Object[] items = new Object[100];
   int putptr, takeptr, count;

   public void put(Object x) throws InterruptedException {
     lock.lock();
     try {
       while (count == items.length) 
         notFull.await();
       items[putptr] = x; 
       if (++putptr == items.length) putptr = 0;
       ++count;
       notEmpty.signal();
     } finally {
       lock.unlock();
     }
   }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值