Lock
Lock是Java 5以后引入的新的API
- ReentrantLock
- 可保证顺序、可查询阻塞Thread list、可设置超时、查询持有lock的Thread
- 注意必须 主动unlock,退出Thread不会清空lock
- CyclicBarrier
- 在await阻塞
- 设置阻塞 的线程数
- 从0递增 数值
- 可以reset 数值
- 到达最大值 放行,await()的Thread
- 可break barrier,唤醒全部线程
- CountDownLatch (比CyclicBarrier少太多方法)
- 在await阻塞
- 设置 阻塞的最大数值
- 从最大值递减
- 数值为0放行,await()的Thread
- 不可reset 数值
- Semaphore
- 设置可用资源的最大值
- 可增 可减数值
- Exchanger
- 在exchange时阻塞,等另一个Thread调用exchange,交换Object
方法
- lock()
- lockInterruptibly()
- interrupt状态无法获得锁
- 等待lock时,如果interrupt则抛异常退出
- tryLock()
- never block
- tryLock(long timeout, TimeUnit timeUnit)
- unlock()
实现类ReentrantLock
- 可以设置timeout
- 可以保证顺序
- 可以查询wait的thread 列表
Lock lock = new ReentrantLock();
lock.lock();
//critical section
lock.unlock();
ReadWriteLock
多线程读(没线程写)、一个线程写
interface
public interface ReadWriteLock {
/**
* Returns the lock used for reading.
*
* @return the lock used for reading
*/
Lock readLock();
/**
* Returns the lock used for writing.
*
* @return the lock used for writing
*/
Lock writeLock();
}
实现类 ReentrantReadWriteLock
ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
readWriteLock.readLock().lock();
// multiple readers can enter this section
// if not locked for writing, and not writers waiting
// to lock for writing.
readWriteLock.readLock().unlock();
readWriteLock.writeLock().lock();
// only one writer can enter this section,
// and only if no threads are currently reading.
readWriteLock.writeLock().unlock();
CyclicBarrier
等到0通行,设置阻塞线程数量
- 设置一个 阻断器,设置阻断线程的数量
- 当阻断到 指定的数量是放行
- 可以设置放行时运行的Runnable
Runnable barrier1Action = new Runnable() {
public void run() {
System.out.println("BarrierAction 1 executed ");
}
};
Runnable barrier2Action = new Runnable() {
public void run() {
System.out.println("BarrierAction 2 executed ");
}
};
CyclicBarrier barrier1 = new CyclicBarrier(2, barrier1Action);
CyclicBarrier barrier2 = new CyclicBarrier(2, barrier2Action);
CyclicBarrierRunnable barrierRunnable1 =
new CyclicBarrierRunnable(barrier1, barrier2);
CyclicBarrierRunnable barrierRunnable2 =
new CyclicBarrierRunnable(barrier1, barrier2);
new Thread(barrierRunnable1).start();
new Thread(barrierRunnable2).start();
public class CyclicBarrierRunnable implements ++Runnable++{
CyclicBarrier barrier1 = null;
CyclicBarrier barrier2 = null;
public CyclicBarrierRunnable(
CyclicBarrier barrier1,
CyclicBarrier barrier2) {
this.barrier1 = barrier1;
this.barrier2 = barrier2;
}
public void run() {
try {
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName() +
" waiting at barrier 1");
this.barrier1.await();
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName() +
" waiting at barrier 2");
this.barrier2.await();
System.out.println(Thread.currentThread().getName() +
" done!");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
}
CountDownLatch
倒计时锁
- 设置初始值
- latch.await();
- latch.countDown(); 到0时放行
Semaphore
允许进入 关键区域的 最大线程数
Semaphore semaphore = new Semaphore(1);
//critical section
semaphore.acquire();
...
semaphore.release();
2. 两个线程通信
- 例如在 insertData到list后,acquire调用
- 在take object from list前,调用release
- 实际上形成一个阻塞队列