思路及其简单:
A线程拿到锁,执行代码B线程拿到锁,执行代码A线程拿到锁,执行代码...... public class FairLockDemo { public static void main(String[] args) { Runnable target = new Runnable(){ int i = 10; // 利用公平锁 private ReentrantLock lock = new ReentrantLock(true); @Override public void run() { while (i >= 0) { try{ lock.lock(); if(i % 2 == 0){ System.out.println("A"); }else { System.out.println("B"); } i--; }finally{ lock.unlock(); } } } }; Thread t1 = new Thread(target, "thread-1"); Thread t2 = new Thread(target, "thread-2"); t1.start(); t2.start(); } }思路比较复杂,值得细细揣摩:
关键点:每个线程都有获得锁的权利1、满足if条件的,wait等待释放锁2、不满足if条件的,执行业务代码 public class TestThead { // 对象锁 private static Object obj = new Object(); private static volatile int num = 10; public static void main(String[] args) { new Thread(new Runnable() { // 匿名内部类 @Override public void run() { synchronized (obj) { while(num > 0){ if(num % 2 == 0){ try { obj.wait(); // 释放锁进入等待队列(等待池),线程2获取到对象锁 } catch (InterruptedException e) { e.printStackTrace(); } } num--; if(num >= 0){ System.out.println("B"); } obj.notify(); // 唤醒等待队列中线程2进入锁池竞争对象锁 } } } }, "thread1").start(); new Thread(new Runnable() { @Override public void run() { synchronized (obj) { while(num > 0){ if(num % 2 != 0){ try { obj.wait(); // 释放锁进入等待队列(等待池),线程1获取到对象锁 } catch (InterruptedException e) { e.printStackTrace(); } } num--; if(num >= 0){ System.out.println("A"); } obj.notify(); // 唤醒等待队列中线程1进入锁池竞争对象锁 } } } }, "thread2").start(); } }思路:
其实和上面的思路差不多只不过上面用了同一个对象锁,思考起来比较麻烦这里采用了两个锁,轮流开闭,思考起来很方便 public class LockCond { private static volatile int count = 10; private static Lock lock = new ReentrantLock(); public static void main(String[] args) { Condition c1 = lock.newCondition(); Condition c2 = lock.newCondition(); new Thread(()->{ while(count > 0) { lock.lock(); try { if(count % 2 == 0) { System.out.println("A"); c1.await(); } //唤醒线程2 c2.signal(); } catch (InterruptedException e) { e.printStackTrace(); } finally { count--; lock.unlock(); } } }) .start(); new Thread(()->{ while(count > 0) { lock.lock(); try { if(count % 2 == 1) { System.out.println("B"); c2.await(); } //唤醒线程1 c1.signal(); } catch (InterruptedException e) { e.printStackTrace(); } finally { count--; lock.unlock(); } } }) .start(); } }