// await()方法会使当前线程等待,同时释放当前锁,当其他线程中使用signal()时或者signalAll()方法时,
// 线程会重新获得锁并继续执行。或者当线程被中断时,也能跳出等待。这和Object.wait()方法很相似。
void await() throws InterruptedException;
// awaitUninterruptibly()方法与await()方法基本相同,但是它并不会再等待过程中响应中断。
void awaitUninterruptibly();
long awaitNanos(long nanosTimeout) throws InterruptedException;
boolean await(long time, TimeUnit unit) throws InterruptedException;
boolean awaitUntil(Date deadline) throws InterruptedException;
// singal()方法用于唤醒一个在等待中的线程。相对的singalAll()方法会唤醒所有在等待中的线程。
// 这和Obejct.notify()方法很类似。
void signal();
void signalAll();
示例
public class ReenterLockCondition implements Runnable{
public static ReentrantLock lock = new ReentrantLock();
public static Condition condition = lock.newCondition();
@Override
public void run() {
try {
lock.lock();
condition.await();
System.out.println("Thread is going on");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
// 注意放到finally中释放
lock.unlock();
}
}
public static void main(String[] args) throws InterruptedException {
ReenterLockCondition t1 = new ReenterLockCondition();
Thread tt = new Thread(t1);
tt.start();
Thread.sleep(2000);
System.out.println("after sleep, signal!");
// 通知线程tt继续执行. 唤醒同样需要重新获得锁
lock.lock();
condition.signal();
lock.unlock();
}
}
Semaphore信号量
锁一般都是互斥排他的, 而信号量可以认为是一个共享锁,
允许N个线程同时进入临界区, 但是超出许可范围的只能等待.
如果N = 1, 则类似于lock.
具体API如下, 通过acquire获取信号量, 通过release释放
1 public void acquire()
2 public void acquireUninterruptibly()
3 public boolean tryAcquire()
4 public boolean tryAcquire(long timeout, TimeUnit unit)
5 public void release()
示例
模拟20个线程, 但是信号量只设置了5个许可.
因此线程是按序每2秒5个的打印job done.
public class SemapDemo implements Runnable{
// 设置5个许可
final Semaphore semp = new Semaphore(5);
@Override
public void run() {
try {
semp.acquire();
// 模拟线程耗时操作
Thread.sleep(2000L);
System.out.println("Job done! " + Thread.currentThread().getId());
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
semp.release();
}
}
public static void main(String[] args){
ExecutorService service = Executors.newFixedThreadPool(20);
final SemapDemo demo = new SemapDemo();
for (int i = 0; i < 20; i++) {
service.submit(demo);
}
}
}
读写分离锁, 可以大幅提升系统并行度.
读-读不互斥:读读之间不阻塞。
读-写互斥:读阻塞写,写也会阻塞读。
写-写互斥:写写阻塞。
示例
使用方法与ReentrantLock类似, 只是读写锁分离.