java.util.concurrent.AbstractExecutorService.java

来源:互联网 发布:民科 知乎 编辑:程序博客网 时间:2024/06/05 05:38

java.util.concurrent.AbstractExecutorService.java

since 1.5

锁是多线程访问共享资源的访问控制工具,通常锁对共享资源都是排它的:一段时间只能有一个线程获得锁,所有对共享资源的访问必须先获得锁。当然有些锁允许对共享资源并发获得锁,如ReadWriteLock.

使用同步方法(synchronized)或代码块可获得与每个对象关联的隐式监视锁(implicit monitor lock), 但是它强制所有锁都以块结构化方式(? block-structured way)获取或释放:当获取了多个锁时, 锁必须以相反的顺序释放,且必须在锁获取的作用范围内释放。

同步方法或代码块的作用范围机制使得使用监视锁(monitor lock)编程非常容易,同时也可避免很多寻常的错误。但有时我们需要以更灵活的方式使用锁,例如有些算法需要遍历可并发访问的数据结构 : 先获得A的锁,再获得B的锁,然后释放A获得C的锁,再释放B的锁获得D的锁等等。
Lock接口的实现类可以在不同范围内获取与释放锁,并且在多个锁的情况下可以以任意顺序获取与释放锁。但其不能够自动释放 锁(同步方法或代码块可以自动释放锁),多数情况下使用方式如下:

    Lock l = ...;    l.lock();    try{        //code    }finally{        l.unlock();    }

当加锁与释放锁发生在不同范围内,必须注意所有在持有锁阶段的代码都需使用try-catch或try-finally来保护以保证当需要时锁被释放。Lock接口的实现类还会尝试以非阻塞的方式来获得锁(tryLock())
Lock类与隐式监视锁行为与语义大不相同,例如顺序保证、非可重复使用、死锁检测。Lock实例也是普通对象,可用在同步代码块作为控制对象。获取Lock实例的监视锁与实例的方法无具体关系。
对传入的任意参数为null均会NullPointerException异常

内存同步

所有Lock的实现类都必须实现相同的由内建监视锁提供的内存同步语义(见Java语言规范)

实现类注意事项

锁的三种不同获取方式(可中断、不可中断、限时)可能会导致它们在性能特征、顺序保证或其它属性上出现差异,另外Lock实现类不一定具有对获取锁过程中断的能力,因此实现类不要求对三种获取锁方式采用相同的语义以及支持中断获取锁的过程,但要求遵守接口中定义的中断语义。

源码

package java.util.concurrent.locks;import java.util.concurrent.TimeUnit;public interface Lock {    /**     * 获取锁.     * <p>如果无法获得锁当前线程被阻塞直到获得锁</p>     * <p>实现类应当能够检测锁的错误使用,如死锁检测,在当前调用会导致死锁的情况下抛出异常</p>     * /    void lock();    /**     * 获取锁除非当前线程中断     * <p>获得锁后立即返回</p>     * <p>如果无法获得锁,当前线程阻塞直到线程获得锁或其它线程中断当前线程且支持锁中断</p>     *     * <p>如果该方法设置了当前线程中断或在获取锁的过程中发生了线程中断,必须支持锁中断,然后抛出InterruptedException异常并清除当前线程的中断状态</p>     */    void lockInterruptibly() throws InterruptedException;    /**     * Acquires the lock only if it is free at the time of invocation.     *     * <p>返回锁是否获取成功     * 如果获取锁失败,当前线程阻塞直到:①当前线程获得锁;②当前线程被中断;③等待时间完成。 锁获取成功返回true,失败返回false,若等待时间≤0,则不等待,等待完成返回false.     *     * @param time 获取锁的最大等待时间     * @param unit 参数的时间单位     * @return 锁获取成功返回true, 失败或时间到达返回false     * @throws InterruptedException      */    boolean tryLock(long time, TimeUnit unit) throws InterruptedException;    /**     * 释放锁     * <p> 通常Lock接口的实现类会强制限制能释放当前锁的线程(通常只有锁的持有者可以释放锁),若违反限制可能抛出异常</p>     */    void unlock();    /**     * 返回一个绑定在当前{@code Lock}实例 上的 {@link Condition}实例     *     * <p>在等待当前condition前当前线程必须获得该锁     * 调用{@link Condition#await()}方法会在方法返回前 在等待与再次获得锁之前自动释放锁      *      * @return A new {@link Condition} instance for this {@code Lock} instance     * @throws UnsupportedOperationException if this {@code Lock}     *         implementation does not support conditions     */    Condition newCondition();}
原创粉丝点击