关键字,无期限等待锁,读读也互斥,代码结束自动释放锁。
obj.wait:释放锁,进入阻塞,等待唤醒(需要拿到锁)
obj.notify:随机唤醒一个(需要拿到锁)
obj.notifyAll:唤醒所有(需要拿到锁)
1 public class SynchronizedTest { 2 3 static final Object obj = new Object(); 4 5 public static void main(String[] args) { 6 for (int i = 0; i < 5; i++) { 7 new Thread(()->{ 8 synchronized(obj) { 9 try { 10 System.out.println(Thread.currentThread().getName() + "开始"); 11 obj.wait(); 12 System.out.println(Thread.currentThread().getName() + "结束"); 13 } catch (InterruptedException e) { 14 e.printStackTrace(); 15 } 16 } 17 }).start(); 18 } 19 try { 20 Thread.sleep(2000); 21 } catch (InterruptedException e) { 22 e.printStackTrace(); 23 } 24 synchronized(obj) { 25 obj.notifyAll(); 26 } 27 } 28 }
接口,可以指定时间尝试获取锁,读读不互斥,代码结束需要主动释放锁。
通过多个Condition可以阶段性地控制多个线程对同一个Lock的访问,类似线程调度的机制。
释放锁放在finally语句块中,是一个写法上的规范。这里讲ReentrantLock,可重入锁。
lock:上锁
tryLock:尝试上锁,可以指定超时时间
unlock:释放锁
condition.await:释放锁,进入阻塞,等待唤醒
condition.signal:随机唤醒一个
condition.signalAll:唤醒所有
1 public class LockTest { 2 3 static final Lock lock = new ReentrantLock(); 4 5 public static void main(String[] args) { 6 for (int i = 0; i < 5; i++) { 7 new Thread(()->{ 8 boolean flag = false; 9 try { 10 flag = lock.tryLock(5000, TimeUnit.MILLISECONDS); 11 if (flag) { 12 System.out.println(Thread.currentThread().getName() + "执行"); 13 Thread.sleep(2000); 14 } 15 } catch (InterruptedException e) { 16 e.printStackTrace(); 17 } finally { 18 if (flag) { 19 lock.unlock(); 20 } 21 } 22 }).start(); 23 } 24 } 25 }
1 public class LockTest { 2 3 static final Lock lock = new ReentrantLock(); 4 static final Condition c1 = lock.newCondition(); 5 static final Condition c2 = lock.newCondition(); 6 7 public static void main(String[] args) { 8 for (int i = 0; i < 5; i++) { 9 new Thread(()->{ 10 try { 11 lock.lock(); 12 System.out.println(Thread.currentThread().getName() + "第一阶段"); 13 c1.await(); 14 System.out.println(Thread.currentThread().getName() + "第二阶段"); 15 c2.await(); 16 System.out.println(Thread.currentThread().getName() + "第三阶段"); 17 } catch (InterruptedException e) { 18 e.printStackTrace(); 19 } finally { 20 lock.unlock(); 21 } 22 }).start(); 23 } 24 try { 25 Thread.sleep(2000); 26 lock.lock(); 27 c1.signalAll(); 28 } catch (InterruptedException e) { 29 e.printStackTrace(); 30 } finally { 31 lock.unlock(); 32 } 33 try { 34 Thread.sleep(2000); 35 lock.lock(); 36 c2.signalAll(); 37 } catch (InterruptedException e) { 38 e.printStackTrace(); 39 } finally { 40 lock.unlock(); 41 } 42 } 43 }
原文:https://www.cnblogs.com/kunwu/p/13629868.html