Lock类

作者: 丹之 | 来源:发表于2018-11-14 17:55 被阅读15次

Lock类

Lock类实际上是一个接口,我们在实例化的时候实际上是实例化实现了该接口的类

Lock lock = new ReentrantLock();

用synchronized的时候,synchronized可以修饰方法,或者对一段代码块进行同步处理。
前面讲过,针对需要同步处理的代码设置对象监视器,比整个方法用synchronized修饰要好。Lock类的用法也是这样,通过Lock对象lock,用lock.lock来加锁,用lock.unlock来释放锁。在两者中间放置需要同步处理的代码。

public class MyConditionService {

    private Lock lock = new ReentrantLock();
    public void testMethod(){
        lock.lock();
        for (int i = 0 ;i < 5;i++){
            System.out.println("ThreadName = " + Thread.currentThread().getName() + (" " + (i + 1)));
        }
        lock.unlock();
    }
}

Lock类其他的功能

如果Lock类只有lock和unlock方法也太简单了,Lock类提供了丰富的加锁的方法和对加锁的情况判断。主要有

实现锁的公平
获取当前线程调用lock的次数,也就是获取当前线程锁定的个数
获取等待锁的线程数
查询指定的线程是否等待获取此锁定
查询是否有线程等待获取此锁定
查询当前线程是否持有锁定
判断一个锁是不是被线程持有
加锁时如果中断则不加锁,进入异常处理
尝试加锁,如果该锁未被其他线程持有的情况下成功

Condition类

Condition是Java提供了来实现等待/通知的类,Condition类还提供比wait/notify更丰富的功能,Condition对象是由lock对象所创建的。但是同一个锁可以创建多个Condition的对象,即创建多个对象监视器。这样的好处就是可以指定唤醒线程。notify唤醒的线程是随机唤醒一个。
下面,看一个例子,显示简单的等待/通知

package Thread.Condition;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class ConditionWaitNotifyService {

    private Lock lock = new ReentrantLock();

    public Condition condition = lock.newCondition();


    public void await(){
        try{
            lock.lock();
            System.out.println("await的时间为 " + System.currentTimeMillis());
            condition.await();
            System.out.println("await结束的时间" + System.currentTimeMillis());

        }catch (Exception e){
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
    }


    public void signal(){
        try{
            lock.lock();
            System.out.println("sign的时间为" + System.currentTimeMillis());
            condition.signal();
        }finally {
            lock.unlock();
        }
    }

    public static void main(String[] args) throws InterruptedException {

        ConditionWaitNotifyService service = new ConditionWaitNotifyService();
        new Thread(service::await).start();
        Thread.sleep(1000 * 3);
        service.signal();
        Thread.sleep(1000);

    }
}

condition对象通过lock.newCondition()来创建,用condition.await()来实现让线程等待,是线程进入阻塞。用condition.signal()来实现唤醒线程。唤醒的线程是用同一个conditon对象调用await()方法而进入阻塞。并且和wait/notify一样,await()和signal()也是在同步代码区内执行。
对于等待/通知机制,简化而言,就是等待一个条件,当条件不满足时,就进入等待,等条件满足时,就通知等待的线程开始执行。为了实现这种功能,需要进行wait的代码部分与需要进行通知的代码部分必须放在同一个对象监视器里面。执行才能实现多个阻塞的线程同步执行代码,等待与通知的线程也是同步进行。对于wait/notify而言,对象监视器与等待条件结合在一起 即synchronized(对象)利用该对象去调用wait以及notify。但是对于Condition类,是对象监视器与条件分开,Lock类来实现对象监视器,condition对象来负责条件,去调用await以及signal。

Condition类的其他功能

和wait类提供了一个最长等待时间,awaitUntil(Date deadline)在到达指定时间之后,线程会自动唤醒。但是无论是await或者awaitUntil,当线程中断时,进行阻塞的线程会产生中断异常。Java提供了一个awaitUninterruptibly的方法,使即使线程中断时,进行阻塞的线程也不会产生中断异常。

相关文章

  • Lock类

    Lock类 Lock类实际上是一个接口,我们在实例化的时候实际上是实例化实现了该接口的类 用synchronize...

  • lock类

    锁接口类继承不可拷贝类 范围锁继承不可拷贝类,里面有继承锁接口类指针,这是什么设计模式呢? lock.h: #if...

  • python threading.Lock

    一.介绍threading模块中的Lock类,Lock类中包含的方法:1.acquire(blocking=Tru...

  • ReentrantLock理解AQS同步队列的细节和设计模式

    Lock接口 Lock的实现 实现Lock接口的类有很多,以下为几个常见的锁实现 ReentrantLock:表示...

  • 29 理解 并发 countDownLatch

    分析lock 锁的原理 基于javaAQS 类封装 ,并发队列lock原理 基于javaAQS类封装 在获取锁的时...

  • Lock 的使用

    Lock 的使用 使用 ReentrantLock 类 lock():获取锁 unlock():释放锁 效果和 s...

  • 并发编程-(6)-AQS原理、一步一步图解Exclusive模式

    目录: 1、Lock介绍 2、Lock的实现类ReentrantLock 3、AQS简介 4、ReentrantL...

  • Lock锁

    synchronized 锁和 Lock 锁的区别 Lock 锁,Java类,synchronized,关键字。s...

  • 2-Lock

    类介绍 类定位 定义了Lock的常用的方法。 类注意事项 lock的常用注意事项在上一章中已经写清楚了。此处主要关...

  • 以ReentrantLock为例分析公平锁和非公平锁

    分析lock() 内部触发了Sync.lock(),Sync这个类有2个实现,FairSync和NonfailrS...

网友评论

      本文标题:Lock类

      本文链接:https://www.haomeiwen.com/subject/geojfqtx.html