﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-nod0620-文章分类-java</title><link>http://www.blogjava.net/nod0620/category/49444.html</link><description /><language>zh-cn</language><lastBuildDate>Fri, 23 Sep 2011 12:44:55 GMT</lastBuildDate><pubDate>Fri, 23 Sep 2011 12:44:55 GMT</pubDate><ttl>60</ttl><item><title>java 线程池</title><link>http://www.blogjava.net/nod0620/articles/359095.html</link><dc:creator>nod0620</dc:creator><author>nod0620</author><pubDate>Tue, 20 Sep 2011 14:27:00 GMT</pubDate><guid>http://www.blogjava.net/nod0620/articles/359095.html</guid><wfw:comment>http://www.blogjava.net/nod0620/comments/359095.html</wfw:comment><comments>http://www.blogjava.net/nod0620/articles/359095.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/nod0620/comments/commentRss/359095.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/nod0620/services/trackbacks/359095.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 图左边是线程池的类结构，右边是放入线程池执行的任务类结构ExecutorServiceExecutorService定义了线程池的基本的方法，AbstractExecutorService是个抽象类，实现了ExecutorService的部分，主要是实现了几个submit()方法，并且提供方法将提交进来的任务封装成FutureTask,ThreadPoolExecutor则实现线程池的管理Futu...&nbsp;&nbsp;<a href='http://www.blogjava.net/nod0620/articles/359095.html'>阅读全文</a><img src ="http://www.blogjava.net/nod0620/aggbug/359095.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/nod0620/" target="_blank">nod0620</a> 2011-09-20 22:27 <a href="http://www.blogjava.net/nod0620/articles/359095.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java thread 之Lock</title><link>http://www.blogjava.net/nod0620/articles/358835.html</link><dc:creator>nod0620</dc:creator><author>nod0620</author><pubDate>Sat, 17 Sep 2011 16:12:00 GMT</pubDate><guid>http://www.blogjava.net/nod0620/articles/358835.html</guid><wfw:comment>http://www.blogjava.net/nod0620/comments/358835.html</wfw:comment><comments>http://www.blogjava.net/nod0620/articles/358835.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/nod0620/comments/commentRss/358835.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/nod0620/services/trackbacks/358835.html</trackback:ping><description><![CDATA[<div>concurrent包里面有很多Lock的具体实现，其具体的实现都是基于AQS实现的<br /><br />ReentrantLock<br />ReentrantLock是可重入的互斥锁，重点是重入和互斥，ReentrantLock 将由最近成功获得锁的线程所持有，当这个线程再次尝试拥有这个Lock时就是重入。互斥就是<br />在某一时间只有一个线程能持有Lock。<br />&nbsp;&nbsp;&nbsp; public void lock() {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sync.lock();<br />&nbsp;&nbsp;&nbsp; }<br />获得锁方法，Sync是AQS的抽象子类，实现可重入和互斥的大部分功能。在Sync的子类中有FairSync和NonfairSync两种代表公平锁策略和非公平锁策略<br /><br />Sync lock方法留给子类去实现，NonfairSync的实现：<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; final void lock() {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (compareAndSetState(0, 1))<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; setExclusiveOwnerThread(Thread.currentThread());<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; acquire(1);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />不管是不是有其他线程在AQS的阻塞的队列里面，如果当前线程能获得线程，就直接获得线程，不行的话执行AQS的acquire()方法，基本就是进入阻塞队列的命了。<br />关键点:AQS的acquire()中调用的tryAcquire(int arg)是留给子类实现的，是在进入阻塞队列前再尝试一次获取锁(lock()方法到这个点上面可能其他线程已经释放锁)<br /><br />NonfairSync的tryAcquire(int arg)调用的nonfairTryAcquire()实现:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; final boolean nonfairTryAcquire(int acquires) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; final Thread current = Thread.currentThread();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int c = getState();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (c == 0) {//关键点1<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (compareAndSetState(0, acquires)) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; setExclusiveOwnerThread(current);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return true;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else if (current == getExclusiveOwnerThread()) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int nextc = c + acquires;//关键点2<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (nextc &lt; 0) // overflow<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw new Error("Maximum lock count exceeded");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; setState(nextc);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return true;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return false;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />关键点1：state为0，没有线程请求锁，直接分配给本线程<br />关键点2.&nbsp; 如果本线程已经得到锁，state加1，即重入。<br /><br />FairSync的实现:<br />&nbsp;&nbsp;&nbsp; final void lock() {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; acquire(1);//关键点1<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp; protected final boolean tryAcquire(int acquires) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; final Thread current = Thread.currentThread();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int c = getState();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (c == 0) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (isFirst(current) &amp;&amp; //关键点2<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; compareAndSetState(0, acquires)) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; setExclusiveOwnerThread(current);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return true;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else if (current == getExclusiveOwnerThread()) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int nextc = c + acquires;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (nextc &lt; 0)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw new Error("Maximum lock count exceeded");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; setState(nextc);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return true;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return false;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />关键点1：公平策略，没有给当前线程优惠<br />关键点2：判断当前线程有没有在阻塞队列的第一位，没在第一位不往下继续执行，这样先给阻塞队列的线程机会，这样做速度比较慢，吞吐量比较小<br /><br />&nbsp;&nbsp;&nbsp; public boolean tryLock() {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return sync.nonfairTryAcquire(1);<br />&nbsp;&nbsp;&nbsp; }<br />&nbsp;tryLock尝试获得锁，不能获得话就直接返回，没有公平策略一说。<br /><br />unlock<br />&nbsp;&nbsp;&nbsp; public void unlock() {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sync.release(1);<br />&nbsp;&nbsp;&nbsp; }<br />&nbsp;<br />&nbsp;&nbsp;&nbsp; public final boolean release(int arg) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (tryRelease(arg)) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Node h = head;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (h != null &amp;&amp; h.waitStatus != 0)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unparkSuccessor(h);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return true;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return false;<br />&nbsp;&nbsp;&nbsp; }<br />tryRelease()留给AQS子类执行：<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; protected final boolean tryRelease(int releases) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int c = getState() - releases;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (Thread.currentThread() != getExclusiveOwnerThread())<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw new IllegalMonitorStateException();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; boolean free = false;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (c == 0) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; free = true;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; setExclusiveOwnerThread(null);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; setState(c);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return free;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />如果state被减后还不为0，表示这个锁被一个线程重入后还没有完全释放，release()方法后面不会执行，也就是不会执行unpark阻塞队列中的线程.<br /><br /><br />ReentrantReadWriteLock<br />ReentrantReadWriteLock内部有两个锁：互斥可重入的WriteLock和共享的ReadLock<br />内部实现中state字段的高16位代表的是read count，低16位代表的是write count<br />AQS的实现也有NonfairSync和FairSync之分：<br />主要区别是同时有读写线程时候对待读写线程策略不同。<br />NonfairSync:<br />final boolean writerShouldBlock(Thread current) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return false; // writers can always barge<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; final boolean readerShouldBlock(Thread current) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* As a heuristic to avoid indefinite writer starvation,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * block if the thread that momentarily appears to be head<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * of queue, if one exists, is a waiting writer. This is<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * only a probablistic effect since a new reader will not<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * block if there is a waiting writer behind other enabled<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * readers that have not yet drained from the queue.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return apparentlyFirstQueuedIsExclusive();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />write永远都不阻塞，read的话看阻塞队列header之后的node是不是write的，如果是就阻塞，可以避免read一直运行导致的write饥饿。<br />FairSync：<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; final boolean writerShouldBlock(Thread current) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // only proceed if queue is empty or current thread at head<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return !isFirst(current);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; final boolean readerShouldBlock(Thread current) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // only proceed if queue is empty or current thread at head<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return !isFirst(current);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />write和read都有判断是不是阻塞队列header后的第一个node。<br /><br />对于ReadLock<br />&nbsp;&nbsp;&nbsp;&nbsp; public void lock() {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sync.acquireShared(1);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />调用AQS的acquireShared()，其中会执行留给AQS子类实现的tryAcquireShared():<br />&nbsp;protected final int tryAcquireShared(int unused) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * Walkthrough:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * 1. If write lock held by another thread, fail<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * 2. If count saturated, throw error<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * 3. Otherwise, this thread is eligible for<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp; lock wrt state, so ask if it should block<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp; because of queue policy. If not, try<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp; to grant by CASing state and updating count.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp; Note that step does not check for reentrant<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp; acquires, which is postponed to full version<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp; to avoid having to check hold count in<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp; the more typical non-reentrant case.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * 4. If step 3 fails either because thread<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp; apparently not eligible or CAS fails,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp; chain to version with full retry loop.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Thread current = Thread.currentThread();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int c = getState();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (exclusiveCount(c) != 0 &amp;&amp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; getExclusiveOwnerThread() != current)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -1;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (sharedCount(c) == MAX_COUNT)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw new Error("Maximum lock count exceeded");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!readerShouldBlock(current) &amp;&amp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; compareAndSetState(c, c + SHARED_UNIT)) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HoldCounter rh = cachedHoldCounter;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (rh == null || rh.tid != current.getId())<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cachedHoldCounter = rh = readHolds.get();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rh.count++;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 1;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return fullTryAcquireShared(current);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />策略是以下的几点：<br />1.如果当前write持有锁，直接返回-1.<br />2.没有write持有锁，判断是否需要阻塞读请求，之后原子更新read count<br />3.上面成功后就返回1，不成功的话在循环中试着读取：<br />&nbsp;&nbsp;&nbsp;&nbsp; final int fullTryAcquireShared(Thread current) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * This code is in part redundant with that in<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * tryAcquireShared but is simpler overall by not<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * complicating tryAcquireShared with interactions between<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * retries and lazily reading hold counts.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HoldCounter rh = cachedHoldCounter;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (rh == null || rh.tid != current.getId())<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rh = readHolds.get();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (;;) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int c = getState();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int w = exclusiveCount(c);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ((w != 0 &amp;&amp; getExclusiveOwnerThread() != current) ||<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((rh.count | w) == 0 &amp;&amp; readerShouldBlock(current)))<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -1;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (sharedCount(c) == MAX_COUNT)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw new Error("Maximum lock count exceeded");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (compareAndSetState(c, c + SHARED_UNIT)) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cachedHoldCounter = rh; // cache for release<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rh.count++;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 1;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />unLock方法就是将read count 减1，然后查看阻塞队列有没有线程需要unpark<br /><br />WriteLock的实现和ReetrantLock的实现是一致的<br />Semaphore<br />Semaphore是信号量的概念，主要控制同一时间内对访问资源的线程数的控制。底层实现是AQS的<br />acquireShared()和releaseShared().<br /><br />CountDownLatch<br />CountDownLatch在完成一组正在其他线程中执行的操作之前，允许线程等待直到他们完成操作<br />await()方法一直等到state=0，初始时CountDownLatch初始化state为传入的数值，一个线程<br />执行操作完成的话执行countDown()方法将state减1，直到为0，await()方法不再阻塞。<br /><br />CyclicBarrier<br />当一组线程调用CyclicBarrier.await()方法，就会阻塞在那里，当最后一个线程进入调用此方法时，就执行<br />一个公共的Runnable.原理是：初始化时有count属性，当前面count-1个线程到来都condition.await()，第count个<br />线程来就执行公共Runnable，然后执行condition.signAll()方法来使得其他线程从阻塞中解脱出来.<br /><br /><br /></div><img src ="http://www.blogjava.net/nod0620/aggbug/358835.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/nod0620/" target="_blank">nod0620</a> 2011-09-18 00:12 <a href="http://www.blogjava.net/nod0620/articles/358835.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java thread 之AQS</title><link>http://www.blogjava.net/nod0620/articles/358638.html</link><dc:creator>nod0620</dc:creator><author>nod0620</author><pubDate>Thu, 15 Sep 2011 14:57:00 GMT</pubDate><guid>http://www.blogjava.net/nod0620/articles/358638.html</guid><wfw:comment>http://www.blogjava.net/nod0620/comments/358638.html</wfw:comment><comments>http://www.blogjava.net/nod0620/articles/358638.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/nod0620/comments/commentRss/358638.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/nod0620/services/trackbacks/358638.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: JDK1.5引入了Doug Lea大神的concurrent框架，其中AbstractQueuedSynchronizer是concurrent框架的基本，从大神的paper中可以看到1.传统的synchronized不能进行中段，这个不合适2.如果将concurrent重心放在少数竞争下优化锁，而在其他情况下放任缓慢执行的策略是不正确的3.需要可预测的维护效率，即使在同步竞争激烈的情况下，理想中...&nbsp;&nbsp;<a href='http://www.blogjava.net/nod0620/articles/358638.html'>阅读全文</a><img src ="http://www.blogjava.net/nod0620/aggbug/358638.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/nod0620/" target="_blank">nod0620</a> 2011-09-15 22:57 <a href="http://www.blogjava.net/nod0620/articles/358638.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java thread</title><link>http://www.blogjava.net/nod0620/articles/358439.html</link><dc:creator>nod0620</dc:creator><author>nod0620</author><pubDate>Wed, 14 Sep 2011 08:53:00 GMT</pubDate><guid>http://www.blogjava.net/nod0620/articles/358439.html</guid><wfw:comment>http://www.blogjava.net/nod0620/comments/358439.html</wfw:comment><comments>http://www.blogjava.net/nod0620/articles/358439.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/nod0620/comments/commentRss/358439.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/nod0620/services/trackbacks/358439.html</trackback:ping><description><![CDATA[<strong>线程状态</strong><br />&nbsp;&nbsp; jdk中线程状态分为:new,runnable,blocked,waiting,timed_waiting,dead.其中new为刚创建还没有开始执行的状态，<br />而runnable状态分为可以执行和正在执行，可以执行是因为可能要等cpu时间片等。blocked状态是指线程在阻塞等待监视器的锁。waiting是指执行了Object.wait()，Thread.join()等方法进入waiting状态；timed_waiting是指带时间数的waiting状态，在时间到达之前都是在waiting状态，dead状态是指结束任务的线程状态，再也不能回到runnable状态了。<br /><br />在线程中有waiting set和ready set概念。<br />当一个对象执行Object.wait()/Object.join()，该线程进入waiting set，同时需要释放监视器的锁。监视器也是一个普通对象，在加上一些关键语法后，就能成为监视器。<br />当一个对象执行Object.notify()时，是在waiting set选择一个thread进入ready set，当这个thread能获得这个监视器的锁时候，就可以进入runnable状态，否则就待在ready set，notifyAll()是通知waiting set里面的所有线程，然后选择其中的一个，不确定是哪一个，线程的优先级也只是一个提示和指导。<br />Object.wait(time)/Object.join(time)方法这些都是在时间限制到达之前thread在waiting set，时间到期之后自动进入ready set。<br />Thread.sleep()/Thread.yield()执行时thread都不会放弃监视器的锁，只是进入ready set，Thread.sleep()只是在指定的时间内休眠，得不到任何的资源.Thread.yield()只是提示thread工作差不多完成了，可以让步给其他Thread，这个让步不保证完成，这个也只对同等级的线程有效。<br /><br /><strong>监视器</strong><br />&nbsp;&nbsp; java使用监视器来表示同步锁，在Java里面，任何一个Object Reference都可以作为同步锁，只要使用synchronized：<br /><div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%;"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">final</span><span style="color: #000000;">&nbsp;Object&nbsp;signal&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;Object(); <br />f1(){<br /></span><span style="color: #0000ff;">&nbsp;&nbsp; synchronized</span><span style="color: #000000;">(signal){<br /><br />&nbsp;&nbsp; }<br />}</span></div>在jvm内部synchronized会被表示成monitorenter和monitorexit;在一个时间段，只有一个线程能持有monitor，也就是在monitorenter里面，也就达到了同步的目的.当想获得一个类变量锁的时候，可以使用这个类的class类。<br /><br /><strong>内存模型</strong><br />在jvm规范中规定java内存模型是java&nbsp; thread&nbsp; work&nbsp; memory和java main&nbsp; memory两部分<br />每个thread一个thread&nbsp; memory，初始为空，必要时和main memory通信<br /><img alt="" src="http://www.blogjava.net/images/blogjava_net/nod0620/thread1.png" height="380" width="469" /><br /><br />规范规定了工作内存和主内存之间通信的8个行为：<strong>use, assign, load, store,read,write, lock, and unlock</strong><br />use:使用一个线程工作内存中的变量，看成线程的行为<br />assign:设置一个线程工作内存中的变量，设置的值来自线程执行引擎，看成线程的行为<br />read：把主内存的值读到线程工作内存当中，看成主内存的行为<br />load：在read之后执行，真正的把值读到到工作内存当中，看成线程的行为<br />store：保存工作内存的值，等下在执行write后传输给主内存，看成线程的行为<br />  <div>write：在store后执行，看成主内存的行为</div>lock和unlock是获取监视器锁和释放锁的行为，是第三方synchronized行为<br /><img alt="" src="http://www.blogjava.net/images/blogjava_net/nod0620/图片2.png" height="251" width="320" /><br /><br />这样的内存模型就会有问题：<br />线程工作内存是独立的，在工作内存A的变量被工作内存B看到需要经过A--&gt;主内存--&gt;B的程度，那么什么时候进行工作内存到主内存的通信呢？<br />这里需要涉及到<span style="font-size: 40pt;"><span style="color: #ff6600; font-family: Wingdings;"></span></span>缓存一致性模型，即工作内存(缓存)什么时候刷新和读取主内存必须遵循一定的规则才可以。  <br />java使用释放一致性模型:在释放锁的时候写入主内存<br />也就是当synchronized表示的方法或者运行块执行结束时监视器锁释放后，里面涉及的所有变量(局部变量除外)的值都写入了主内存，当变量被其他线程看到的话，其值是最新的。<br />那么方法或运行块未进行同步，可能有两方面的问题:<br />1.方法的执行顺序是未定的<br />2.即使方法的执行顺序是相同的，由于工作内存的值未写到主内存中也有可能有问题<br /><br />thread在jvm当中执行的顺序和代码中看到的顺序可能是不一样的，为了性能优化等代码可能进行重排序，所有jmm定义了<br />线程的执行顺序模型：happens-before模型，规则如下:<br />1.一个线程当中，先出现的指令happens-before后出现的指令<br />2.构造器的里面指令happens-before创建对象的指令<br />3.对于一个监视器，unlock&nbsp; happens-before 想去得锁的指令<br />4.对于volatile的变量，write happens-before read<br />5.A call to start() on a thread happens-before any actions in the started thread.<br />6.All actions in a thread happen-before any other thread successfully returns from a<br />join() on that thread.<br />  <br /><div>happens-before模型保证了JMM内存模型的访问方式。<br />对于synchronized我们可以认为他符合了上面的第3点<br />对于volatile变量，保证了在线程每次修改后马上反映到主内存当中，也就是可见性。</div><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />1.All instance fields, static fields and array elements are stored in heap memory.存放在java堆内<br />2.<img src ="http://www.blogjava.net/nod0620/aggbug/358439.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/nod0620/" target="_blank">nod0620</a> 2011-09-14 16:53 <a href="http://www.blogjava.net/nod0620/articles/358439.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>