锁的本质是对于系统资源的锁定占有和释放,以此来控制代码在多线程模式下的执行顺序
- BlockingQueue 阻塞队列实现,有点类似于Semaphore
BlockingQueue foo = new BlockingQueue(1);
BlockingQueue bar = new BlockingQueue(1);
fun1() {
foo.put();
// do
bar.put();
}
func2() {
bar.take();
// do
foo.take();
}
- CyclicBarrier 循环屏障,控制一组线程执行到某个条件后才会继续执行
// 控制三个线程
CyclicBarrier cyc = new CyclicBarrier(3);
Thread1 执行 cyc.await();
Thread2 执行 cyc.await();
Thread3 执行 cyc.await();
只有三个线程都执行了cyc.await();三个线程才能同时放开继续执行
- Thread.yield() 线程让出CPU资源
Thread().yeild() // 线程主动从运行态度变成就绪态,需要注意有种情况,线程a主动让出执行权后又立即被选中,这个方法不能完全保证顺序
- ReentrantLock 可重入锁
ReentrantLock + Condition可以控制交互执行
ReentrantLock lock = new ReentrantLock();
Condition cond = lock.newCondition();
lock.lock();
try {
cond.await(); // 同 obj.wait() 线程自我阻塞
// do something;
cond.signal(); // 同obj.release() 线程释放
} finally {
// 使用的时候注意一定要释放,否则会造成不断自旋或者异常导致死锁
lock.unlock();
}
- synchronized 原生关键字
Object lock = new Object();
synchronized(lock) {
// do something
}
- Semaphore 信号量控制
Semaphore a = new Semaphore();
Semaphore b = new Semaphore();
func1(){
a.require();
dosomething...
b.release();
}
func2(){
b.require();
dosomething...
a.release();
}
Q.E.D.