1. 概述
LockSupport是一个非常方便实用的线程阻塞工具,它可以在线程内任意位置让线程阻塞。
和Thread.suspend相比,它弥补了由于 resume在前发生,导致线程无法继续执行的情况。
和Object.wait()相比,它不需要先获得某个对象的锁,也不会抛出 InterruptedException异常。
Lock Support的静态方法 park()可以阻塞当前线程,类似的还有 parkNanos()、 parkUntil()等方法。
它们实现了一个限时的等待
2. 主要接口
LockSupport.park();
LockSupport.unpark(Thread t);
3. 与suspend()比较
不容易引起线程冻结
因为 LockSupport类使用类似信号量的机制。它为每一个线程准备了一个许可,如果许可可用,那么 park()函数会立即返回,并且消费这个许可(也就是将许可变为不可用),
如果许可不可用,就会阻塞。而 unpack则使得一个许可变为可用(但是和信号量不同的是,许可不能累加,你不可能拥有超过一个许可,它永远只有一个)。
特点:
即使 unpark()操作发生在 park()之前,它也可以使下一次的 park()操作立即返回。
这也就是上述代码可顺利结束的主要原因同时,处于park()挂起状态的线程不会像suspend()那样还给出一个令人费解的Runnable的状态。
它会非常明确地给出一个 WAITING状态,甚至还会标注是park()引起的。
4.中断响应
能够响应中断,但不抛出异常。
中断响应的结果是,park()函数的返回,可以从Thread.interrupted()得到中断标志
package com.john.learn.high.concurent.ch03.tools;
import java.util.Iterator;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.LockSupport;
public class CountDownLatch {
private AtomicInteger count;
private int _startCount;
private ConcurrentLinkedQueue<Thread> threadQueue = new ConcurrentLinkedQueue<Thread>();
public CountDownLatch(int count) {
this.count = new AtomicInteger(count);
_startCount = count;
}
public void await() throws InterruptedException {
if (this.count.get() == 0) {
return;
}
threadQueue.add(Thread.currentThread());
LockSupport.park(this);
if (Thread.interrupted()) {
throw new InterruptedException();
}
}
public void countDown() {
int _count = count.decrementAndGet();
if (_count == 0) {
Thread thread = null;
while ((thread = threadQueue.poll()) != null) {
if (thread.isInterrupted() || !thread.isAlive()) {
continue;
}
LockSupport.unpark(thread);
}
}
}
public int getCount() {
return _startCount;
}
}