Condition
ConditionWait
public class ConditionDemoWait implements Runnable{ private Lock lock; private Condition condition; public ConditionDemoWait(Lock lock, Condition condition){ this.lock=lock; this.condition=condition; } @Override public void run() { System.out.println("begin -ConditionDemoWait"); ry { lock.lock(); condition.await(); System.out.println("end -ConditionDemoWait"); } catch (InterruptedException e) { e.printStackTrace(); }finally { lock.unlock(); } } }
ConditionSignal
public class ConditionDemoSignal implements Runnable{ private Lock lock; private Condition condition; public ConditionDemoSignal(Lock lock,Condition condition){ this.lock=lock; this.condition=condition; } @Override public void run() { System.out.println("begin -ConditionDemoSignal"); try { lock.lock(); condition.signal();System.out.println("end - ConditionDemoSignal"); }finally { lock.unlock(); } } }

condition.await
public final void await() throws InterruptedException { if (Thread.interrupted()) //表示 await 允许被中断 throw new InterruptedException(); Node node = addConditionWaiter(); //创建一个新的节点,节点状态为 condition,采用的数据结构仍然是链表 int savedState = fullyRelease(node); //释放当前的锁,得到锁的状态,并唤醒 AQS 队列中的一个线程 int interruptMode = 0; //如果当前节点没有在同步队列上,即还没有被 signal,则将当前线程阻塞 while (!isOnSyncQueue(node)) {//判断这个节点是否在 AQS 队列上,第一次判断的是 false,因为前面已经释放锁了 LockSupport.park(this); //通过 park 挂起当前线程 if ((interruptMode =checkInterruptWhileWaiting(node)) != 0) break; } // 当这个线程醒来,会尝试拿锁, 当 acquireQueued返回 false 就是拿到锁了. // interruptMode != THROW_IE -> 表示这个线程没有成功将 node 入队,但 signal 执行了 enq 方法让其入队了. // 将这个变量设置成 REINTERRUPT. if (acquireQueued(node, savedState) && interruptMode != THROW_IE) interruptMode = REINTERRUPT; // 如果 node 的下一个等待者不是 null, 则进行清理,清理 Condition 队列上的节点. // 如果是 null ,就没有什么好清理的了. if (node.nextWaiter != null) // clean up if cancelled unlinkCancelledWaiters(); // 如果线程被中断了,需要抛出异常.或者什么都不做 if (interruptMode != 0) reportInterruptAfterWait(interruptMode); }
addConditionWaiter
private Node addConditionWaiter() { Node t = lastWaiter; // 如 果 lastWaiter 不 等 于 空 并 且waitStatus 不等于 CONDITION 时,把冲好个节点从链表中移除 if (t != null && t.waitStatus !=Node.CONDITION) { unlinkCancelledWaiters(); t = lastWaiter; } //构建一个 Node,waitStatus=CONDITION。这里的链表是一个单向的,所以相比 AQS 来说会简单很多 Node node = new Node(Thread.currentThread(),Node.CONDITION); if (t == null) firstWaiter = node; else t.nextWaiter = node; lastWaiter = node; return node; }

fullyRelease
final int fullyRelease(Node node) { boolean failed = true; try { int savedState = getState(); //获得重入的次数 if (release(savedState)) {//释放锁并且唤醒下一个同步队列中的线程 failed = false; return savedState; } else { throw new IllegalMonitorStateException(); } } finally { if (failed) node.waitStatus =Node.CANCELLED; } }

isOnSyncQueue
final boolean isOnSyncQueue(Node node) { if (node.waitStatus ==Node.CONDITION || node.prev == null) return false; if (node.next != null) // If hassuccessor, it must be on queue return true; return findNodeFromTail(node); }
Condition.signal
public final void signal() { if (!isHeldExclusively()) //先判断当前线程是否获得了锁,这个判断比较简单,直接用获得锁的线程和当前线程相比即可 throw new IllegalMonitorStateException(); Node first = firstWaiter; // 拿到 Condition队列上第一个节点 if (first != null) doSignal(first); }
Condition.doSignal
private void doSignal(Node first) { do { //从 Condition 队列中删除 first 节点 if ( (firstWaiter = first.nextWaiter)== null) lastWaiter = null; // 将 next 节点设置成 nullfirst.nextWaiter = null; } while (!transferForSignal(first) &&(first = firstWaiter) != null); }
AQS.transferForSignal
final boolean transferForSignal(Node node){ if (!compareAndSetWaitStatus(node, Node.CONDITION, 0))//更新节点的状态为 0,如果更新失败,只有一种可能就是节点被 CANCELLED 了 return false; Node p = enq(node);//调用 enq,把当前节点添加到AQS 队列。并且返回返回按当前节点的上一个节点,也就是原tail 节点 int ws = p.waitStatus;// 如果上一个节点的状态被取消了, 或者尝试设置上一个节点的状态为 SIGNAL 失败了(SIGNAL 表示: 他的 next节点需要停止阻塞), if (ws > 0|| !compareAndSetWaitStatus(p, ws,Node.SIGNAL)) LockSupport.unpark(node.thread); // 唤醒节点上的线程. return true; //如果 node 的 prev 节点已经是signal 状态,那么被阻塞的 ThreadA 的唤醒工作由 AQS 队列来完成 }
public final void await() throws InterruptedException { if (Thread.interrupted()) throw new InterruptedException(); Node node =addConditionWaiter(); int savedState =fullyRelease(node); int interruptMode = 0; while (!isOnSyncQueue(node)) { LockSupport.park(this); if ((interruptMode =checkInterruptWhileWaiting(node)) != 0) break; } if (acquireQueued(node,savedState) && interruptMode !=THROW_IE) interruptMode = REINTERRUPT; if (node.nextWaiter != null) // clean up if cancelled unlinkCancelledWaiters(); if (interruptMode != 0) reportInterruptAfterWait(interruptMode); }
checkInterruptWhileWaiting
private int checkInterruptWhileWaiting(Node node) { return Thread.interrupted() ?(transferAfterCancelledWait(node) ?THROW_IE : REINTERRUPT) :0; } final boolean transferAfterCancelledWait(Node node) {//使用 cas 修改节点状态,如果还能修改成功,说明线程被中断时,signal 还没有被调用。 // 这里有一个知识点,就是线程被唤醒,并不一定是在 java 层面执行了locksupport.unpark,也可能是调用了线程的 interrupt()方法,这个方法会更新一个中断标识,并且会唤醒处于阻塞状态下的线程。 if(compareAndSetWaitStatus(node,Node.CONDITION, 0)) { enq(node); //如果 cas 成功,则把node 添加到 AQS 队列 return true; } //如果 cas 失败,则判断当前 node 是否已经在 AQS 队列上,如果不在,则让给其他线程执行 //当 node 被触发了 signal 方法时,node 就会被加到 aqs 队列上 while (!isOnSyncQueue(node))//循环检测 node 是否已经成功添加到 AQS 队列中。如果没有,则通过 yield, Thread.yield(); return false; }
acquireQueued
private void reportInterruptAfterWait(int interruptMode) throws InterruptedException { if (interruptMode == THROW_IE) throw new InterruptedException(); else if (interruptMode ==REINTERRUPT) selfInterrupt(); }

CountDownLatch
public static void main(String[] args) throws InterruptedException { CountDownLatch countDownLatch=new CountDownLatch(3); new Thread(()->{ System.out.println(""+Thread.currentThread().getName()+"-执行中"); countDownLatch.countDown(); System.out.println(""+Thread.currentThread().getName()+"-执行完毕"); },"t1").start(); new Thread(()->{ System.out.println(""+Thread.currentThread().getName()+"-执行中"); countDownLatch.countDown(); System.out.println(""+Thread.currentThread().getName()+"-执行完毕"); },"t2").start(); new Thread(()->{ System.out.println(""+Thread.currentThread().getName()+"-执行中"); countDownLatch.countDown();System.out.println(""+Thread.currentThread().getName()+"-执行完毕"); },"t3").start(); countDownLatch.await(); System.out.println("所有线程执行完毕"); }

static CountDownLatch countDownLatch=new CountDownLatch(1); @Override public void run() { try { countDownLatch.await(); //TODO } catch (InterruptedException e){ e.printStackTrace(); } System.out.println("ThreadName:"+Thread.currentThread().getName()); } public static void main(String[]args) throws InterruptedException { for(int i=0;i<1000;i++){ new Demo().start(); } countDownLatch.countDown(); }
CountDownLatch

acquireSharedInterruptibly
public final void acquireSharedInterruptibly(int arg) throws InterruptedException { if (Thread.interrupted()) throw new InterruptedException(); if (tryAcquireShared(arg) < 0) //state 如果不等于 0,说明当前线程需要加入到共享锁队列中 doAcquireSharedInterruptibly(arg); }
doAcquireSharedInterruptibly
private void doAcquireSharedInterruptibly(int arg) throws InterruptedException { final Node node = addWaiter(Node.SHARED); //创建一个共享模式的节点添加到队列中 boolean failed = true; try { for (;;) { final Node p = node.predecessor(); if (p == head) { int r = tryAcquireShared(arg);//就判断尝试获取锁 if (r >= 0) {//r>=0 表示获取到了执行权限,这个时候因为 state!=0,所以不会执行这段代码 setHeadAndPropagate(node, r); p.next = null; // help GC failed = false; return; } } //阻塞线程 if (shouldParkAfterFailedAcquire(p,node) &&parkAndCheckInterrupt()) throw newInterruptedException(); } } finally { if (failed) cancelAcquire(node); } }

CountDownLatch.countDown
public final boolean releaseShared(int arg) { if (tryReleaseShared(arg)) { doReleaseShared(); return true; } return false; } //用自旋的方法实现 state 减 1protected boolean tryReleaseShared(int releases) { // Decrement count; signal when transition to zero for (;;) { int c = getState(); if (c == 0) return false; int nextc = c-1; if (compareAndSetState(c,nextc)) return nextc == 0; } }
AQS. doReleaseShared
private void doReleaseShared() { for (;;) { Node h = head; if (h != null && h != tail){ int ws = h.waitStatus; if (ws == Node.SIGNAL) { if(!compareAndSetWaitStatus(h,Node.SIGNAL, 0)) continue; // loop to recheck cases unparkSuccessor(h); } // 这个 CAS 失败的场景是:执行到这里的时候,刚好有一个节点入队,入队会将这个 ws 设置为 -1 else if (ws == 0 && !compareAndSetWaitStatus(h, 0, Node.PROPAGATE)) continue; // loop on failed CAS } // 如果到这里的时候,前面唤醒的线程已经占领了 head,那么再循环 // 通过检查头节点是否改变了,如果改变了就继续循环 if (h == head) // loop if head changed break; } }
private void doAcquireSharedInterruptibly(int arg) throws InterruptedException { final Node node =addWaiter(Node.SHARED); boolean failed = true; try { for (;;) {//被唤醒的线程进入下一次循环继续判断 final Node p =node.predecessor(); if (p == head) { int r =tryAcquireShared(arg); if (r >= 0) { setHeadAndPropagate(node, r);p.next = null; //把当前节点移除 aqs 队列 failed = false; return; } } if(shouldParkAfterFailedAcquire(p,node) && parkAndCheckInterrupt()) throw new InterruptedException(); } } finally { if (failed) cancelAcquire(node); } }
setHeadAndPropagate
ThreadB
private void setHeadAndPropagate(Node node, int propagate) { Node h = head; // Record old head for check below setHead(node); if (propagate > 0 || h == null|| h.waitStatus < 0 ||(h = head) == null ||h.waitStatus < 0) { Node s = node.next; if (s == null ||s.isShared()) doReleaseShared(); }}

Semaphore
public class Test { public static void main(String[] args) { Semaphore semaphore=new Semaphore(5); for(int i=0;i<10;i++){ new Car(i,semaphore).start(); } } static class Car extends Thread{ private int num; private Semaphore semaphore; public Car(int num, Semaphore semaphore) { this.num = num; his.semaphore = semaphore; } public void run(){ try { semaphore.acquire();//获取一个许可 System.out.println("第"+num+"占用一个停车位");TimeUnit.SECONDS.sleep(2); System.out.println("第"+num+"俩车走喽"); semaphore.release(); } catch (InterruptedException e) { e.printStackTrace(); } } } }
FairSync
static final class FairSync extends Sync { private static final long serialVersionUID = 2014338818796000944L; FairSync(int permits) { super(permits); } protected int tryAcquireShared(int acquires) { for (;;) {// 区别就在于是不是会先判断是否有线程在排队,然后才进行 CAS 减操作 if(hasQueuedPredecessors()) return -1; int available = getState(); int remaining = available- acquires; if (remaining < 0 ||compareAndSetState(available,remaining)) return remaining; } } }
NofairSync
static final class NonfairSync extends Sync { private static final long serialVersionUID = -2694183684443567898L; NonfairSync(int permits) { super(permits); } protected int tryAcquireShared(int acquires) { return nonfairTryAcquireShared(acquires); } } final int nonfairTryAcquireShared(int acquires) { for (;;) { int available = getState();int remaining = available -acquires; if (remaining < 0 || compareAndSetState(available,remaining)) return remaining; } }
CyclicBarrier
DataImportThread
public class DataImportThread extends Thread{ private CyclicBarrier cyclicBarrier; private String path; public DataImportThread(CyclicBarrier cyclicBarrier, String path) { this.cyclicBarrier =cyclicBarrier; this.path = path; } @Override public void run() { System.out.println("开始导入:"+path+"位置的数据"); try { cyclicBarrier.await();//阻塞 } catch(InterruptedException e) { e.printStackTrace(); } catch(BrokenBarrierException e) { e.printStackTrace(); } } }
CycliBarrierDemo
public class CycliBarrierDemo extends Thread{ @Override public void run() { System.out.println("开始进行数据分析"); } public static void main(String[] args) { CyclicBarrier cycliBarrier=new CyclicBarrier(3,newCycliBarrierDemo()); new Thread(new DataImportThread(cycliBarrier,"file1")).start(); new Thread(new DataImportThread(cycliBarrier,"file2")).start(); new Thread(new DataImportThread(cycliBarrier,"file3")).start();} }

来源:博客园
作者:千里送e毛
链接:https://www.cnblogs.com/qlsem/p/11495190.html