Java多线程深入学习-Lock,ReadWriteLock,Condition接口定义

1.Lock接口

/**
 * 定义锁接口
 * 	接口支持那些语义不同(重入、公平等)的锁规则,可以在非阻塞式结构的上下文(包括 hand-over-hand 和锁重排算法)中使用这些规则。
 * 	主要的实现是 ReentrantLock。
 */
public interface Lock {

	/*在Lock中声明了四个方法来获取锁,那么这四个方法有何区别呢?
	 * 首先,lock()方法是平常使用得最多的一个方法,就是用来获取锁。
	 * 如果锁已被其他线程获取,则进行等待。
	 * 在前面已经讲到,如果采用Lock,必须主动去释放锁,并且在发生异常时,不会自动释放锁。
	 * 因此,一般来说,使用Lock必须在try…catch…块中进行,并且将释放锁的操作放在finally块中进行,以保证锁一定被被释放,防止死锁的发生。
	 */
	/** 获取锁 */
    void lock();
    /*lockInterruptibly()方法比较特殊,当通过这个方法去获取锁时,
     * 如果线程 正在等待获取锁,则这个线程能够 响应中断,即中断线程的等待状态。
     * 例如,当两个线程同时通过lock.lockInterruptibly()想获取某个锁时,假若此时线程A获取到了锁,而线程B只有在等待,
     * 	那么对线程B调用threadB.interrupt()方法能够中断线程B的等待过程。
     */
    /** 如果当前线程未被中断,则获取锁,可以响应中断 */
    void lockInterruptibly() throws InterruptedException;

    /*tryLock()方法是有返回值的,它表示用来尝试获取锁,如果获取成功,则返回true;
     * 如果获取失败(即锁已被其他线程获取),则返回false,
     * 也就是说,这个方法无论如何都会立即返回(在拿不到锁时不会一直在那等待)
     */
    /** 仅在调用时锁为空闲状态才获取该锁,可以响应中断   */
    boolean tryLock();
    /*tryLock(long time, TimeUnit unit)方法和tryLock()方法是类似的,
     * 只不过区别在于这个方法在拿不到锁时会等待一定的时间,在时间期限之内如果还拿不到锁,就返回false,
     * 同时可以响应中断。如果一开始拿到锁或者在等待期间内拿到了锁,则返回true。
     */
    /** 如果锁在给定的等待时间内空闲,并且当前线程未被中断,则获取锁   */
    boolean tryLock(long time, TimeUnit unit) throws InterruptedException;

    /** 释放锁  */
    void unlock();
    /** 返回绑定到此 Lock 实例的新 Condition 实例  */
    Condition newCondition();
}

2.ReadWriteLock接口

/** 读写锁接口 */
public interface ReadWriteLock {
    /** 获取读锁 */
    Lock readLock();

    /** 获取写锁 */
    Lock writeLock();
}

3.Condition接口

/**
 * 接口描述了可能会与锁有关联的条件变量。	使用时需要和一个Lock绑定
 * 这些变量在用法上与使用 Object.wait 访问的隐式监视器类似,但提供了更强大的功能。
 * 需要特别指出的是,单个 Lock 可能与多个 Condition 对象关联。
 * 为了避免兼容性问题,Condition 方法的名称与对应的 Object 版本中的不同。
 */
public interface Condition {
	/** 调用此方法的线程将加入等待队列,阻塞直到被通知或线程发生中断 */
    void await() throws InterruptedException;
    /** 调用此方法的线程将加入等待队列,阻塞 直到被通知*/
    void awaitUninterruptibly();
    /** 调用此方法的线程加入等待队列,阻塞直到被通知或发生中断或者超出等待的时间 */
    long awaitNanos(long nanosTimeout) throws InterruptedException;
    /** 调用此方法的线程加入等待队列,阻塞直到被通知或发生中断或者超出等待的时间 (指定时间单位)*/
    boolean await(long time, TimeUnit unit) throws InterruptedException;
    /** 调用此方法的线程加入等待队列,阻塞直到被通知或发生中断或者超出特定的日期时间 */
    boolean awaitUntil(Date deadline) throws InterruptedException;
    /** 唤醒一个等待中的线程 */
    void signal();
    /** 唤醒所有等待中的线程 */
    void signalAll();
}

4.LockSupport类

/**
 * LockSupport是一个线程阻塞工具类,所有的方法都是静态方法,可以让线程在任意位置阻塞或唤醒
 */
@SuppressWarnings("unused")
public class LockSupport {
    private LockSupport() {} // Cannot be instantiated.

    private static void setBlocker(Thread t, Object arg) {
        UNSAFE.putObject(t, parkBlockerOffset, arg);
    }
    /** 恢复当前线程 */
    public static void unpark(Thread thread) {
        if (thread != null)
            UNSAFE.unpark(thread);
    }
    /** 暂停当前线程 */
    public static void park() {
        UNSAFE.park(false, 0L);
    }
    public static void park(Object blocker) {
        Thread t = Thread.currentThread();
        setBlocker(t, blocker);
        UNSAFE.park(false, 0L);
        setBlocker(t, null);
    }
    
    /** 暂停当前线程,不过有超时时间的限制 */
    public static void parkNanos(long nanos) {
        if (nanos > 0)
            UNSAFE.park(false, nanos);
    }
    public static void parkNanos(Object blocker, long nanos) {
        if (nanos > 0) {
            Thread t = Thread.currentThread();
            setBlocker(t, blocker);
            UNSAFE.park(false, nanos);
            setBlocker(t, null);
        }
    }
    
    /** 暂停当前线程,直到某个时间 */
    public static void parkUntil(long deadline) {
        UNSAFE.park(true, deadline);
    }
    public static void parkUntil(Object blocker, long deadline) {
        Thread t = Thread.currentThread();
        setBlocker(t, blocker);
        UNSAFE.park(true, deadline);
        setBlocker(t, null);
    }

    public static Object getBlocker(Thread t) {
        if (t == null)
            throw new NullPointerException();
        return UNSAFE.getObjectVolatile(t, parkBlockerOffset);
    }


    static final int nextSecondarySeed() {
        int r;
        Thread t = Thread.currentThread();
        if ((r = UNSAFE.getInt(t, SECONDARY)) != 0) {
            r ^= r << 13;   // xorshift
            r ^= r >>> 17;
            r ^= r << 5;
        }
        else if ((r = java.util.concurrent.ThreadLocalRandom.current().nextInt()) == 0)
            r = 1; // avoid zero
        UNSAFE.putInt(t, SECONDARY, r);
        return r;
    }

    private static final sun.misc.Unsafe UNSAFE;
    private static final long parkBlockerOffset;
    private static final long SEED;
	private static final long PROBE;
    private static final long SECONDARY;
    static {
        try {
            UNSAFE = sun.misc.Unsafe.getUnsafe();
            Class<?> tk = Thread.class;
            parkBlockerOffset = UNSAFE.objectFieldOffset
                (tk.getDeclaredField("parkBlocker"));
            SEED = UNSAFE.objectFieldOffset
                (tk.getDeclaredField("threadLocalRandomSeed"));
            PROBE = UNSAFE.objectFieldOffset
                (tk.getDeclaredField("threadLocalRandomProbe"));
            SECONDARY = UNSAFE.objectFieldOffset
                (tk.getDeclaredField("threadLocalRandomSecondarySeed"));
        } catch (Exception ex) { throw new Error(ex); }
    }

}

猜你喜欢

转载自blog.csdn.net/luo_mu_hpu/article/details/107743448