锁的本质是对于系统资源的锁定占有和释放,以此来控制代码在多线程模式下的执行顺序

  1. BlockingQueue 阻塞队列实现,有点类似于Semaphore
BlockingQueue foo = new BlockingQueue(1);
BlockingQueue bar = new BlockingQueue(1);

fun1() {
    foo.put();
    // do
    bar.put();
}

func2() {
    bar.take();
    // do
    foo.take();
}
  1. CyclicBarrier 循环屏障,控制一组线程执行到某个条件后才会继续执行
// 控制三个线程
CyclicBarrier cyc = new CyclicBarrier(3);

Thread1 执行 cyc.await();
Thread2 执行 cyc.await();
Thread3 执行 cyc.await();

只有三个线程都执行了cyc.await();三个线程才能同时放开继续执行
  1. Thread.yield() 线程让出CPU资源
Thread().yeild() // 线程主动从运行态度变成就绪态,需要注意有种情况,线程a主动让出执行权后又立即被选中,这个方法不能完全保证顺序
  1. 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();
}
  1. synchronized 原生关键字
Object lock = new Object();
synchronized(lock) {
    // do something
}
  1. Semaphore 信号量控制
Semaphore a = new Semaphore();
Semaphore b = new Semaphore();

func1(){
    a.require();
    dosomething...
    b.release();
}

func2(){
    b.require();
    dosomething...
    a.release();
}


Q.E.D.


每一个平凡的日常都是连续的奇迹