﻿<?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-文章分类-多线程</title><link>http://www.blogjava.net/nod0620/category/45893.html</link><description /><language>zh-cn</language><lastBuildDate>Sun, 02 Oct 2011 19:34:10 GMT</lastBuildDate><pubDate>Sun, 02 Oct 2011 19:34:10 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>并发程序的性能思考</title><link>http://www.blogjava.net/nod0620/articles/328815.html</link><dc:creator>nod0620</dc:creator><author>nod0620</author><pubDate>Fri, 13 Aug 2010 15:10:00 GMT</pubDate><guid>http://www.blogjava.net/nod0620/articles/328815.html</guid><wfw:comment>http://www.blogjava.net/nod0620/comments/328815.html</wfw:comment><comments>http://www.blogjava.net/nod0620/articles/328815.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/nod0620/comments/commentRss/328815.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/nod0620/services/trackbacks/328815.html</trackback:ping><description><![CDATA[&nbsp; 首先说下线程的死锁，个人想法（从艺术家吃饭说起）：<br />
&nbsp; 1.必须有资源想被多个线程独占，但是资源不能共享，也就是一次只能一个线程用<br />
&nbsp; 2.一个线程抢占一个资源然后再等待另外一个线程（大家都这样）<br />
&nbsp; 3.资源不能被强占，大家都是优先级相同的线程，都在那里等<br />
&nbsp; 4.发生循环等待了（多个锁）<br />
&nbsp;避免死锁就是打破上面任何一条<br />
<br />
&nbsp;&nbsp;&nbsp; 一个并发程序好坏大致需要两个方面：响应速度和伸缩性，也即是有多快和有多少，这往往是相互矛盾的两方面，我们需要做的就是平衡这两方面。<br />
&nbsp;&nbsp;&nbsp; 从并发程序的特点看，我们可以从以下几方面入手性能的优化：<br />
&nbsp;&nbsp;&nbsp; 1 多线程执行那么必须在多个线程里面上下切换，这需要操作系统保存上个线程的多线程，创建或者唤醒下个线程，这个都消耗资源。所以减少上下文切换，可以增加伸缩性（多几个线程执行）<br />
&nbsp;&nbsp;&nbsp; 2&nbsp; synchronized同步块，同步块意味着这个里面是单线程执行的，既是串行执行，其中synchronized保持了内存的可见性和原子性，volatile保证了可见性，这都使得线程的工作内存的内容每一次都要交换到主内存中，这样的话工作内存的缓存失效，所以尽量的缩小同步，也可以使用concurrent包的lock显示锁定。<br />
&nbsp;&nbsp; 3&nbsp; 阻塞，这个看看io和nio就知道了，可以将阻塞的操作移除出我们主要的线程，另外起线程处理<br />
&nbsp;&nbsp; 4&nbsp; 锁，这个在并发中很重要，可以减小持有的锁的时间（尽量的缩小同步块等），减少对锁的占用时间，比如拆分锁，读写分离锁，或者是分成好几个锁（concurrenthashmap），把独占锁分成多个锁<br />
&nbsp;&nbsp; 5&nbsp; 线程池管理线程的创建和生命周期，减少创建和销毁线程的消耗<br />
&nbsp;&nbsp; 6.不可变对象，抛弃一切的同步<br />
<br />
&nbsp;最重要的是在这之前我们需要审视我的环境：cpu，网络，i/0，数据库等等<br />
&nbsp;&nbsp;&nbsp; <br />
<br />
<img src ="http://www.blogjava.net/nod0620/aggbug/328815.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> 2010-08-13 23:10 <a href="http://www.blogjava.net/nod0620/articles/328815.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Read—Write Lock Pattern</title><link>http://www.blogjava.net/nod0620/articles/328577.html</link><dc:creator>nod0620</dc:creator><author>nod0620</author><pubDate>Wed, 11 Aug 2010 14:31:00 GMT</pubDate><guid>http://www.blogjava.net/nod0620/articles/328577.html</guid><wfw:comment>http://www.blogjava.net/nod0620/comments/328577.html</wfw:comment><comments>http://www.blogjava.net/nod0620/articles/328577.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/nod0620/comments/commentRss/328577.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/nod0620/services/trackbacks/328577.html</trackback:ping><description><![CDATA[Read—Write Lock Pattern将读写分离，在读取之前，获得用来读取的锁，在写在之前，获得用来写入的锁，<br />
读写的锁的关系是：有人读取（多个也无所谓）时，写不能进行；有人写入时，其他的写和读不能进行。<br />
<br />
代码如下：<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;">package</span><span style="color: #000000;">&nbsp;readwritelock;<br />
<br />
<br />
</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;Data&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">final</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">char</span><span style="color: #000000;">[]&nbsp;buffer;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">final</span><span style="color: #000000;">&nbsp;ReadWriteLock&nbsp;readWriteLock&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;ReadWriteLock();<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;Data(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;size){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">this</span><span style="color: #000000;">.buffer</span><span style="color: #000000;">=</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">char</span><span style="color: #000000;">[size];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">&nbsp;(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;i&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;&nbsp;i&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;buffer.length;&nbsp;i</span><span style="color: #000000;">++</span><span style="color: #000000;">)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;buffer[i]&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">'</span><span style="color: #000000;">*</span><span style="color: #000000;">'</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">char</span><span style="color: #000000;">[]&nbsp;&nbsp;read(){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;readWriteLock.readLock();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">try</span><span style="color: #000000;">{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;doRead();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span><span style="color: #0000ff;">finally</span><span style="color: #000000;">{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;readWriteLock.readUnLock();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;write(</span><span style="color: #0000ff;">char</span><span style="color: #000000;">&nbsp;c){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;readWriteLock.writeLock();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">try</span><span style="color: #000000;">{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;doWrite(c);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span><span style="color: #0000ff;">finally</span><span style="color: #000000;">{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;readWriteLock.writeUnLock();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">char</span><span style="color: #000000;">[]&nbsp;doRead(){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">try</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Thread.sleep(</span><span style="color: #000000;">200</span><span style="color: #000000;">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: #0000ff;">catch</span><span style="color: #000000;">&nbsp;(InterruptedException&nbsp;e)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;TODO&nbsp;Auto-generated&nbsp;catch&nbsp;block</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;buffer;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;doWrite(</span><span style="color: #0000ff;">char</span><span style="color: #000000;">&nbsp;c){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">&nbsp;(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;i&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;&nbsp;i&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;buffer.length;&nbsp;i</span><span style="color: #000000;">++</span><span style="color: #000000;">)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;buffer[i]&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">c;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
<br />
}<br />
</span><span style="color: #008000;">/**</span><span style="color: #008000;">****************************************</span><span style="color: #008000;">*/</span><span style="color: #000000;"><br />
</span><span style="color: #0000ff;">package</span><span style="color: #000000;">&nbsp;readwritelock;<br />
<br />
<br />
</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;ReadThread&nbsp;</span><span style="color: #0000ff;">extends</span><span style="color: #000000;">&nbsp;Thread&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;Data&nbsp;data;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;ReadThread(Data&nbsp;data)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">this</span><span style="color: #000000;">.data&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;data;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;run()&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">while</span><span style="color: #000000;">&nbsp;(</span><span style="color: #0000ff;">true</span><span style="color: #000000;">)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">char</span><span style="color: #000000;">[]&nbsp;c&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;data.read();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(Thread.currentThread().getName()&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">:&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;String.valueOf(c));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
}<br />
</span><span style="color: #008000;">/**</span><span style="color: #008000;">****************************************</span><span style="color: #008000;">*/</span><span style="color: #000000;"><br />
</span><span style="color: #0000ff;">package</span><span style="color: #000000;">&nbsp;readwritelock;<br />
<br />
<br />
</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;ReadWriteLock&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">volatile</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;readLocks&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">volatile</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;writeLocks&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">volatile</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;waitLocks&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">volatile</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">boolean</span><span style="color: #000000;">&nbsp;writeFirst&nbsp;</span><span style="color: #000000;">=</span><span style="color: #0000ff;">true</span><span style="color: #000000;">;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">synchronized</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;readLock()&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;写锁或者等待锁大于0，读阻塞</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">while</span><span style="color: #000000;">&nbsp;(writeLocks&nbsp;</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">||</span><span style="color: #000000;">&nbsp;writeFirst</span><span style="color: #000000;">&amp;&amp;</span><span style="color: #000000;">waitLocks&nbsp;</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">try</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;wait();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: #0000ff;">catch</span><span style="color: #000000;">&nbsp;(InterruptedException&nbsp;e)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;TODO&nbsp;Auto-generated&nbsp;catch&nbsp;block</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;readLocks</span><span style="color: #000000;">++</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">synchronized</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;readUnLock()&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;readLocks</span><span style="color: #000000;">--</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;writeFirst&nbsp;</span><span style="color: #000000;">=</span><span style="color: #0000ff;">true</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;notifyAll();<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">synchronized</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;writeLock()&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;写等待</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;waitLocks</span><span style="color: #000000;">++</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">try</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">while</span><span style="color: #000000;">&nbsp;(readLocks&nbsp;</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">||</span><span style="color: #000000;">writeLocks</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">0</span><span style="color: #000000;">)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;wait();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: #0000ff;">catch</span><span style="color: #000000;">&nbsp;(InterruptedException&nbsp;e)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;TODO&nbsp;Auto-generated&nbsp;catch&nbsp;block</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span><span style="color: #0000ff;">finally</span><span style="color: #000000;">{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;waitLocks&nbsp;</span><span style="color: #000000;">--</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;writeLocks</span><span style="color: #000000;">++</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">synchronized</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;writeUnLock()&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;writeLocks</span><span style="color: #000000;">--</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;writeFirst&nbsp;</span><span style="color: #000000;">=</span><span style="color: #0000ff;">false</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;notifyAll();<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
}<br />
</span><span style="color: #008000;">/**</span><span style="color: #008000;">******************************************</span><span style="color: #008000;">*/</span><span style="color: #000000;"><br />
</span><span style="color: #0000ff;">package</span><span style="color: #000000;">&nbsp;readwritelock;<br />
<br />
</span><span style="color: #0000ff;">import</span><span style="color: #000000;">&nbsp;java.util.Random;<br />
<br />
</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;WriterThread&nbsp;</span><span style="color: #0000ff;">extends</span><span style="color: #000000;">&nbsp;Thread&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;Data&nbsp;data;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;String&nbsp;str;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;index&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;WriterThread(Data&nbsp;data,&nbsp;String&nbsp;str)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">this</span><span style="color: #000000;">.data&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;data;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">this</span><span style="color: #000000;">.str&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;str;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;run(){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">while</span><span style="color: #000000;">(</span><span style="color: #0000ff;">true</span><span style="color: #000000;">){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;data.write(get());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">try</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Thread.sleep(</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;Random().nextInt(</span><span style="color: #000000;">200</span><span style="color: #000000;">));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: #0000ff;">catch</span><span style="color: #000000;">&nbsp;(InterruptedException&nbsp;e)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;TODO&nbsp;Auto-generated&nbsp;catch&nbsp;block</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">char</span><span style="color: #000000;">&nbsp;get(){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">char</span><span style="color: #000000;">&nbsp;a&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">str.charAt(index);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;index</span><span style="color: #000000;">++</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">(index</span><span style="color: #000000;">&gt;=</span><span style="color: #000000;">str.length()){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;index&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;a;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
}<br />
</span><span style="color: #008000;">/**</span><span style="color: #008000;">******************************************</span><span style="color: #008000;">*/</span><span style="color: #000000;"><br />
</span><span style="color: #0000ff;">package</span><span style="color: #000000;">&nbsp;readwritelock;<br />
<br />
</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;Test&nbsp;{<br />
</span><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;">void</span><span style="color: #000000;">&nbsp;main(String[]&nbsp;args)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;Data&nbsp;data&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;Data(</span><span style="color: #000000;">10</span><span style="color: #000000;">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;WriterThread(data,&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">asdsad</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;WriterThread(data,&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">有亲戚吗</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;ReadThread(data).start();<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
}<br />
}<br />
</span></div>
<br />
jdk concurrent 包里面有CurrentHashMap和CopyOnWriteArrayList都有锁的概念<br />
CurrentHashMap有个分离锁，把Map分成几个段，对于一个段的写入，不影响其他段的读写，<br />
CopyOnWriteArrayList可以并发的读取，并且返回一个稳定的迭代器，对于写入，是重新开辟一个数组，拷贝原来的数据进行修改，修改完成后再合并回去.&nbsp; <br />
&nbsp; jdk concurrent的 ReentrantReadWriteLock就是一个可以冲入的读写锁<br />
<br />
<img src ="http://www.blogjava.net/nod0620/aggbug/328577.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> 2010-08-11 22:31 <a href="http://www.blogjava.net/nod0620/articles/328577.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>guarded suspension pattern和productor-consumer pattern</title><link>http://www.blogjava.net/nod0620/articles/328223.html</link><dc:creator>nod0620</dc:creator><author>nod0620</author><pubDate>Sat, 07 Aug 2010 17:32:00 GMT</pubDate><guid>http://www.blogjava.net/nod0620/articles/328223.html</guid><wfw:comment>http://www.blogjava.net/nod0620/comments/328223.html</wfw:comment><comments>http://www.blogjava.net/nod0620/articles/328223.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/nod0620/comments/commentRss/328223.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/nod0620/services/trackbacks/328223.html</trackback:ping><description><![CDATA[&nbsp;请求发出以后，如果没有准备好的一直等待到数据准备好在返回---》谨慎的等待（恶心的名字）<br />
<div style="background-color: rgb(238, 238, 238); font-size: 13px; border: 1px solid rgb(204, 204, 204); 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: rgb(0, 0, 255);">package</span><span style="color: rgb(0, 0, 0);">&nbsp;guarded;<br />
<br />
</span><span style="color: rgb(0, 0, 255);">import</span><span style="color: rgb(0, 0, 0);">&nbsp;java.util.concurrent.ArrayBlockingQueue;<br />
</span><span style="color: rgb(0, 0, 255);">import</span><span style="color: rgb(0, 0, 0);">&nbsp;java.util.concurrent.BlockingQueue;<br />
<br />
</span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);">&nbsp;Data&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">private</span><span style="color: rgb(0, 0, 0);">&nbsp;BlockingQueue</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">String</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;blockingQueue&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);">&nbsp;ArrayBlockingQueue</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">String</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp; public void putRequest(String content){<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; try {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; blockingQueue.put(content);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; } catch (InterruptedException e) {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // TODO Auto-generated catch block<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; e.printStackTrace();<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; }</span><span style="color: rgb(0, 0, 0);"><br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);">&nbsp;String&nbsp;getRequest(){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">try</span><span style="color: rgb(0, 0, 0);">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);">&nbsp;blockingQueue.take();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: rgb(0, 0, 255);">catch</span><span style="color: rgb(0, 0, 0);">&nbsp;(InterruptedException&nbsp;e)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">&nbsp;TODO&nbsp;Auto-generated&nbsp;catch&nbsp;block</span><span style="color: rgb(0, 128, 0);"><br />
</span><span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">""</span><span style="color: rgb(0, 0, 0);">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
}<br />
</span><span style="color: rgb(0, 128, 0);">/**</span><span style="color: rgb(0, 128, 0);">****************************************</span><span style="color: rgb(0, 128, 0);">*/</span><span style="color: rgb(0, 0, 0);"><br />
<br />
<br />
</span><span style="color: rgb(0, 0, 255);">package</span><span style="color: rgb(0, 0, 0);">&nbsp;guarded;<br />
<br />
</span><span style="color: rgb(0, 0, 255);">import</span><span style="color: rgb(0, 0, 0);">&nbsp;java.util.Random;<br />
<br />
</span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);">&nbsp;ClientThread&nbsp;</span><span style="color: rgb(0, 0, 255);">extends</span><span style="color: rgb(0, 0, 0);">&nbsp;Thread{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">private</span><span style="color: rgb(0, 0, 0);">&nbsp;Data&nbsp;data;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);">&nbsp;ClientThread(Data&nbsp;data){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">.data&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">data;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);">&nbsp;run(){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">for</span><span style="color: rgb(0, 0, 0);">&nbsp;(</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);">&nbsp;i&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">;&nbsp;i&nbsp;</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">1000</span><span style="color: rgb(0, 0, 0);">;&nbsp;i</span><span style="color: rgb(0, 0, 0);">++</span><span style="color: rgb(0, 0, 0);">)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">put&nbsp;content:</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);">i);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;data.putRequest(String.valueOf(i));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">try</span><span style="color: rgb(0, 0, 0);">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Thread.sleep(</span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);">&nbsp;Random().nextInt(</span><span style="color: rgb(0, 0, 0);">1000</span><span style="color: rgb(0, 0, 0);">));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: rgb(0, 0, 255);">catch</span><span style="color: rgb(0, 0, 0);">&nbsp;(InterruptedException&nbsp;e)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">&nbsp;TODO&nbsp;Auto-generated&nbsp;catch&nbsp;block</span><span style="color: rgb(0, 128, 0);"><br />
</span><span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
}<br />
</span><span style="color: rgb(0, 128, 0);">/**</span><span style="color: rgb(0, 128, 0);">********************************</span><span style="color: rgb(0, 128, 0);">*/</span><span style="color: rgb(0, 0, 0);"><br />
<br />
</span><span style="color: rgb(0, 0, 255);">package</span><span style="color: rgb(0, 0, 0);">&nbsp;guarded;<br />
<br />
</span><span style="color: rgb(0, 0, 255);">import</span><span style="color: rgb(0, 0, 0);">&nbsp;java.util.Random;<br />
<br />
</span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);">&nbsp;ServerThread&nbsp;</span><span style="color: rgb(0, 0, 255);">extends</span><span style="color: rgb(0, 0, 0);">&nbsp;Thread&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">private</span><span style="color: rgb(0, 0, 0);">&nbsp;Data&nbsp;data;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);">&nbsp;ServerThread(Data&nbsp;data){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">.data&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">data;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);">&nbsp;run(){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">while</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 255);">true</span><span style="color: rgb(0, 0, 0);">){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">get&nbsp;content:</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);">data.getRequest());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">try</span><span style="color: rgb(0, 0, 0);">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Thread.sleep(</span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);">&nbsp;Random().nextInt(</span><span style="color: rgb(0, 0, 0);">1000</span><span style="color: rgb(0, 0, 0);">));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: rgb(0, 0, 255);">catch</span><span style="color: rgb(0, 0, 0);">&nbsp;(InterruptedException&nbsp;e)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">&nbsp;TODO&nbsp;Auto-generated&nbsp;catch&nbsp;block</span><span style="color: rgb(0, 128, 0);"><br />
</span><span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
}<br />
</span><span style="color: rgb(0, 128, 0);">/**</span><span style="color: rgb(0, 128, 0);">*******************************</span><span style="color: rgb(0, 128, 0);">*/</span><span style="color: rgb(0, 0, 0);"><br />
</span><span style="color: rgb(0, 0, 255);">package</span><span style="color: rgb(0, 0, 0);">&nbsp;guarded;<br />
<br />
</span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);">&nbsp;Test&nbsp;{<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 128, 0);">/**</span><span style="color: rgb(0, 128, 0);"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span style="color: rgb(128, 128, 128);">@param</span><span style="color: rgb(0, 128, 0);">&nbsp;args<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 128, 0);">*/</span><span style="color: rgb(0, 0, 0);"><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">static</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);">&nbsp;main(String[]&nbsp;args)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Data&nbsp;data&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);">&nbsp;Data();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);">&nbsp;ServerThread(data).start();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);">&nbsp;ClientThread(data).start();<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
}<br />
</span></div>
guarded suspension pattern和productor-comsumer(生产者消费者)很像，这里Data的<span style="color: rgb(0, 0, 0);">blockingQueue的容量是1，</span>productor-comsumer则大于一，productor-comsumer也基本上是多对多关系。<br />
jdk1.4以前主要用wait（），notifyAll（）进行控制，现在用<span style="color: rgb(0, 0, 0);">BlockingQueue</span><span style="color: rgb(0, 0, 0);">更加简单</span><br />
<br />
参与者：<br />
Data（存放资源和等待条件等一系列条件和业务处理的类）&nbsp; <span style="color: rgb(0, 0, 0);">ServerThread和</span><span style="color: rgb(0, 0, 0);">ClientThread（处理结果和请求发起的线程）<br />
<br />
<br />
</span><br />
<br />
<br />
<img src ="http://www.blogjava.net/nod0620/aggbug/328223.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> 2010-08-08 01:32 <a href="http://www.blogjava.net/nod0620/articles/328223.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>single thread execution</title><link>http://www.blogjava.net/nod0620/articles/328208.html</link><dc:creator>nod0620</dc:creator><author>nod0620</author><pubDate>Sat, 07 Aug 2010 16:16:00 GMT</pubDate><guid>http://www.blogjava.net/nod0620/articles/328208.html</guid><wfw:comment>http://www.blogjava.net/nod0620/comments/328208.html</wfw:comment><comments>http://www.blogjava.net/nod0620/articles/328208.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/nod0620/comments/commentRss/328208.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/nod0620/services/trackbacks/328208.html</trackback:ping><description><![CDATA[single thread execution主要思想是：在同一时刻，对于某一共享资源，只能有一个人访问，即资源同步。<br />
<br />
<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;">package</span><span style="color: #000000;">&nbsp;gate;<br />
<br />
</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;Person&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;String&nbsp;name;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;String&nbsp;address;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">synchronized</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;&nbsp;setNameAddress(String&nbsp;name,String&nbsp;address){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">this</span><span style="color: #000000;">.name&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;name;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">this</span><span style="color: #000000;">.address&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;address;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;check();<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;check(){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">(</span><span style="color: #000000;">!</span><span style="color: #000000;">name.equals(address)){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="color: #000000;">"</span><span style="color: #000000;">problem:</span><span style="color: #000000;">"</span><span style="color: #000000;">+</span><span style="color: #000000;">name</span><span style="color: #000000;">+</span><span style="color: #000000;">"</span><span style="color: #000000;">,</span><span style="color: #000000;">"</span><span style="color: #000000;">+</span><span style="color: #000000;">address);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
}<br />
<br />
</span><span style="color: #008000;">/**</span><span style="color: #008000;">**************************</span><span style="color: #008000;">*/</span><span style="color: #000000;"><br />
<br />
</span><span style="color: #0000ff;">package</span><span style="color: #000000;">&nbsp;gate;<br />
<br />
</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;RunThread&nbsp;</span><span style="color: #0000ff;">extends</span><span style="color: #000000;">&nbsp;Thread&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;Person&nbsp;person;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;String&nbsp;name;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;String&nbsp;address;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;RunThread(Person&nbsp;person,String&nbsp;name,String&nbsp;address){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">this</span><span style="color: #000000;">.person&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">person;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">this</span><span style="color: #000000;">.name&nbsp;&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">name;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">this</span><span style="color: #000000;">.address&nbsp;&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">address;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;run(){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">while</span><span style="color: #000000;">(</span><span style="color: #0000ff;">true</span><span style="color: #000000;">){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;person.setNameAddress(name,address);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
}<br />
</span><span style="color: #008000;">/**</span><span style="color: #008000;">****************************</span><span style="color: #008000;">*/</span><span style="color: #000000;"><br />
</span><span style="color: #0000ff;">package</span><span style="color: #000000;">&nbsp;gate;<br />
<br />
</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;Test&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><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;">void</span><span style="color: #000000;">&nbsp;main(String[]&nbsp;args)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Person&nbsp;person&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;Person();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;RunThread(person,</span><span style="color: #000000;">"</span><span style="color: #000000;">345</span><span style="color: #000000;">"</span><span style="color: #000000;">,</span><span style="color: #000000;">"</span><span style="color: #000000;">345</span><span style="color: #000000;">"</span><span style="color: #000000;">).start();<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;RunThread(person,</span><span style="color: #000000;">"</span><span style="color: #000000;">456</span><span style="color: #000000;">"</span><span style="color: #000000;">,</span><span style="color: #000000;">"</span><span style="color: #000000;">456</span><span style="color: #000000;">"</span><span style="color: #000000;">).start();<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
}<br />
<br />
</span></div>
<br />
参与者如下：<br />
共享资源（<span style="color: #000000;">Person </span>），资源利用者<span style="color: #000000;">（RunThread） <br />
对于共享资源中的线程非安全方法需要加入锁机制(</span><span style="color: #0000ff;">synchronized或者</span>ReentrantLock<span style="color: #000000;">)进行同步，确保在某个时间点只有一个线程在访问该方法。<br />
适应的时机：<br />
多线程环境（废话），资源共享（又是废话），资源的状态发生变化（状态不会变化的对象线程安全的）<br />
<br />
<br />
</span>
<img src ="http://www.blogjava.net/nod0620/aggbug/328208.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> 2010-08-08 00:16 <a href="http://www.blogjava.net/nod0620/articles/328208.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>