??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲真人无码永久在线观看,亚洲国产精品成人精品无码区 ,亚洲乱码国产一区三区http://www.tkk7.com/evanwhj/category/8117.htmlJava, software development and others.zh-cnTue, 27 Feb 2007 21:49:12 GMTTue, 27 Feb 2007 21:49:12 GMT60多线E?7): JTW?章笔?/title><link>http://www.tkk7.com/evanwhj/archive/2006/03/11/34879.html</link><dc:creator>Evan</dc:creator><author>Evan</author><pubDate>Sat, 11 Mar 2006 15:11:00 GMT</pubDate><guid>http://www.tkk7.com/evanwhj/archive/2006/03/11/34879.html</guid><wfw:comment>http://www.tkk7.com/evanwhj/comments/34879.html</wfw:comment><comments>http://www.tkk7.com/evanwhj/archive/2006/03/11/34879.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/evanwhj/comments/commentRss/34879.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/evanwhj/services/trackbacks/34879.html</trackback:ping><description><![CDATA[     摘要: 《Java Threads》的W?章“Minimal Synchronization Techniques”,是这本书中到现在我认为最差的一章了Q当然主要是我不喜欢JDK 1.5新推出的Atomic ClassQ而这一章却׃不少章来介l,且牵强地攚w打字程序,又语焉不详地指出q种攚w的困难之处和可能带来的副作用,但却又不能从代码的实际运行中看到q种副作用,很有误导初学者的嫌疑。不q,我想Q没有哪个初学者会冒风险ؓ了用Atomic Class而将原本单明了的法攚w得如此晦ӆ难懂Qƈ且还有潜在的出错风险。所以,对于Atomic ClassQ我跌不读Q绝Ҏ(gu)有什么损失。不q对于其中?.1.3 Double-Checked Locking”和?.3 Thread Local Variables”这两节倒要着重读一读,其是Thread LocalQ应该说是Java中一个比较重要的多线E工兗?nbsp; <a href='http://www.tkk7.com/evanwhj/archive/2006/03/11/34879.html'>阅读全文</a><img src ="http://www.tkk7.com/evanwhj/aggbug/34879.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/evanwhj/" target="_blank">Evan</a> 2006-03-11 23:11 <a href="http://www.tkk7.com/evanwhj/archive/2006/03/11/34879.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>多线E?6): Java Threads例子的一个问?/title><link>http://www.tkk7.com/evanwhj/archive/2006/03/09/34556.html</link><dc:creator>Evan</dc:creator><author>Evan</author><pubDate>Thu, 09 Mar 2006 14:11:00 GMT</pubDate><guid>http://www.tkk7.com/evanwhj/archive/2006/03/09/34556.html</guid><wfw:comment>http://www.tkk7.com/evanwhj/comments/34556.html</wfw:comment><comments>http://www.tkk7.com/evanwhj/archive/2006/03/09/34556.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/evanwhj/comments/commentRss/34556.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/evanwhj/services/trackbacks/34556.html</trackback:ping><description><![CDATA[看到《Java Threads》第5章,介绍了JDK 1.5新加的一些所谓原子类(Atomic Classes)QL觉有点ؓ原子而原子,实际操作中,又有多少ZZ许的性能提升而刻意去用这些别扭的操作而放弃直观的synchronize关键字或者LockcdQ不q,q里不是惌个,而是当其用Atomic Classes来改造它的打字程序后Q解释用原子cd是保证类似递增、递减、赋值等操作的原子性,而不能保证其所在的Ҏ(gu)一定是U程安全的,然后_有可能按键事件的处理可能需要等待resetScore()处理完才能执行,而这会导致错误的评分Q被当成多敲了键Q。由于前几章的内容相Ҏ(gu)较简单易懂,所以也没有很仔l的q行那些例子。这里ؓ了验证一下,p行了一下第4章的例子Q然后发玎ͼ基本上第一ơ的评分L错的。这引起了我的注意Q因为,一般情况下Q如果是race conditionD的错误是很难重现的,q么明显的错误很可能是程序逻辑上的错误。仔l看了一下代码,发现在start按钮的事件处理方法里Q有下面q样一D代码:<br /> <div id="tnmmfrp" class="mycode">startButton.addActionListener(new ActionListener() {<br />        public void actionPerformed(ActionEvent evt) {<br />                displayCanvas.setDone(false);<br />                producer.setDone(false);<br />                startButton.setEnabled(false);<br />                stopButton.setEnabled(true);<br />                feedbackCanvas.setEnabled(true);<br />                feedbackCanvas.requestFocus();<br />                score.resetScore();<br />            }<br />        });</div> 注意重置成W的调用放在了最后,此时Q随机生成字W的U程应该被唤醒ƈ产生了第一个字W,然后QresetScore()需要输入的字符又设成了-1Q所以,当你W一ơ输入字W时QL被认为是多击了一ơ键而扣1?(。既然这P那停止然后再启动也应该会发生q个错误啊。而事实上的确是这栗我惻Iq不应该看做是race condition吧,有什么样的同步技术能够避免这个问题呢Q除非另外弄个标志,当成l没有被重置前,不能产生W一个字W。当Ӟq是不需要的Q只要将score.resetScore()攑ֈW一句就可以了?br /><br />然后又运行了W?章的例子Q发现基本上没有q个问题。难道第3章的代码是正的Q打开源代码一看,重置成W的方法还是放在最后,那这里ؓ什么又是正的呢?我想Q大U是W?章的例子中,每次点击start按钮Q都重新创徏一个线E对象的原因吧。由于创建对象和初始化线E需要一定的旉Q刚好给了主U程重置成W的机会?br /><br />不知道作者有意ؓ之呢Q还是疏忽,不过Q这L(fng)错误不能是race condition的例子?img src ="http://www.tkk7.com/evanwhj/aggbug/34556.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/evanwhj/" target="_blank">Evan</a> 2006-03-09 22:11 <a href="http://www.tkk7.com/evanwhj/archive/2006/03/09/34556.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>多线E?5): JTW?章笔?/title><link>http://www.tkk7.com/evanwhj/archive/2006/03/06/33938.html</link><dc:creator>Evan</dc:creator><author>Evan</author><pubDate>Mon, 06 Mar 2006 14:21:00 GMT</pubDate><guid>http://www.tkk7.com/evanwhj/archive/2006/03/06/33938.html</guid><wfw:comment>http://www.tkk7.com/evanwhj/comments/33938.html</wfw:comment><comments>http://www.tkk7.com/evanwhj/archive/2006/03/06/33938.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/evanwhj/comments/commentRss/33938.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/evanwhj/services/trackbacks/33938.html</trackback:ping><description><![CDATA[<a href="http://www.tkk7.com/evanwhj/archive/2006/03/05/33768.html">W??/a>主要介绍了数据的同步(Data Synchronization)Q这一章则主要介绍U程之间的同步方?Thread Notification)Q同样包括传l的wait-and-notifyҎ(gu)和JDK 1.5新推出的Condition Variable。在多线E编E中Q数据同步和U程同步是两个最基本也是最关键的部分?br />《Java Threads》一书中通过考察打字E序中当按下start和stop按钮后,每次都创Z个新的线E的效率问题来引入线E同步的概念Q当然不是线E同步的主要用处。不q,教科书归教科书,实际q用则又是另一回事。所以,通过书本学习语法Q通过实践来获得运用经验?br /><br /> <h4>4.1 Wait and Notify</h4> 1. {待/唤醒cM于Solaris或POSIX中的条g变量(conditon variables)Q或者Windows中的事g变量(evant variable)或者信号量(signal)Q用于某?多个U程暂停{待某个条g的满I而该条g由其它U程来设|的情况?br />2. 在Java中,像每个对象有一个锁之外QQ何对象都可以提供{待/唤醒的机制。就像Java中的synchronizedL表示获得某个具体对象的锁一Pwait和notify也L{待某个具体的对象,q由该对象唤醒;同样Q获得某个对象上的锁不一定是该对象需要同步一P{待和唤醒的条g也不一定是与之l定的对象?br />3. Java中wait-and-notify的几个方法: <div id="kehrlka" class="mycode">void wait(): 使当前线E处于等待状态,直到其它U程调用了nofity()或者notifyAll()Ҏ(gu)为止?br />void wait(long timeout): 使当前线E处于等待状态,直到其它U程调用了nofity()或者notifyAll()Ҏ(gu)Q或者超q了指定的时?单位为ms)为止<br />void wait(long timeout, int nanos)Q与wait(long)一P只是在某些JVM中可以精到奈秒?br />void notify(): 唤醒<strong><font color="#ff0000">一?/font></strong>正在{待该对象的U程?br />void notifyAll(): 唤醒<strong><font color="#ff0000">所?/font></strong>正在{待该对象的U程?</div> 注意Q?strong>M{待和唤醒方法都必须在与之对应的对象的同步方法或同步块里调用?/strong>卻Iwait-and-notify必须和与之对应的synchronized关键词一起用的?br />4. wait()和sleep()的主要区别:<br />  1) sleep()可以在Q何地方调用,而wait()需要在同步Ҏ(gu)或同步块中调用;<br />  2) q入wait()函数ӞJVM会自动释NQ而当从wait()q回卌唤醒Ӟ又会自动获得锁;而sleep()没有q个功能Q因此如果在wait()的地方用sleep()代替Q则会导致相应的nofity()Ҏ(gu)在等待时不可能被触发Q因为notify()必须在相应的同步Ҏ(gu)或同步块中,而此时这个锁却被sleep()所在的Ҏ(gu)占用。也是_wait-and-notify不可能与sleep()同时使用?br /><br /><strong>4.1.1 The Wait-and-Notify Mechanism and Synchronization</strong><br />1. q一节详l的讲解了wait-and-notify机制和synchronized的关p,主要是两点:1)wait-and-notify必须和synchronized同时使用Q?)wait()会自动释攑֒获取锁;<br />2. q一节中举了一个例子用来解释可能存在当条g被不满时也有可能被唤醒的情况: <div id="usizrlu" class="mycode">  1) U程T1调用一个同步方法;<br />  2) T1状态变量,发现其不满条gQ?br />  3) T1调用wait()Qƈ释放锁;<br />  4) U程T2调用另外一个同步方法,获得锁;<br />  5) U程T3调用另外一个同步方法,׃T2获得了锁Q所以处于等待状态;<br />  6) T2修改状态变量,使其满条gQƈ调用notify()Ҏ(gu)Q?br />  7) T3获得锁,然后处理数据Qƈ状态变量又讄Z满条g的状态;<br />  8) T3处理完毕q回Q?br />  9) T1被唤醒,但实际上此时条gq不满?</div> q个例子刚好印证了《Effective Java》中"Item 50: Never invoke wait outside a loop"和《Practical Java》中"实践54Q针对wait()和notifyAll()使用旋锁(spin locks)"。即L用下面这U方式来调用wait(): <div id="mlcxogf" class="mycode"> <pre> synchronized(obj) { while(<condition does not hold>) wait(); <br /> ... // Perform action appropriate to condition }</pre> </div> 或者象《Practical Java》中一P <div id="vulnprf" class="mycode"> <pre> synchronized(obj) { while(<condition does not hold>) { try { wait(); } catch (InterruptedException e) {} }<br /><br /> ... // Perform action appropriate to condition }</pre> </div> 3. 调用wait()的线ET可能在以下几U情况被唤醒Q?br />  1) 其它U程调用了notify()Q而刚好线ET得到了通知Q?br />  2) 其它U程调用了notifyAll()Q?br />  3) 其它U程中断了线ETQ?br />  4) ׃JVM的原因,D了spurious wakeup?br /><br /><strong>4.1.2 wait(), notify(), and notifyAll()</strong><br />1. 正像多个U程{待同一对象上的锁,当锁释放Ӟ无法定哪个U程会得到那个锁一P当有多个U程在wait()Ӟ当另外一个线E调用nofity()的时候,也不能确定哪个线E会被唤醒; 2. 因此在《Practical Java》的"实践53Q优先用notifyAll()而非notify()"的一Pl合实践54Q可以比较好的解决线E唤醒的问题?br /><br /><strong>4.1.3 Wait-and-Notify Mechanism with Synchronized blocks</strong><br />再次必须在同一个对象的synchronizedҎ(gu)或块内调用该对象上的wait和notifyҎ(gu)?br /><br /> <h3>4.2 Condition Variables</h3> 1. 像上面反复的一Pwait-and-notify机制是与特定对象及其上的锁是l定在一L(fng)Q锁和唤醒对象不能分开Q这在某些情况下不是很方便;<br />2. JDK 1.5提供Condition接口来提供与其它pȝ几乎一致的condition variables机制Q?br />3. Condition对象由Lock对象的newCondition()Ҏ(gu)生成Q从而允怸个锁产生多个条g变量Q可以根据实际情冉|{待不同条gQ?br />4. 该书的例子没有什么特别的实际意义Q但JDK 1.5文档中提供了一个例子,能充分说明用Condition Variables使得E序更加清晰易读Q也更有效率Q? <div id="cprtkrl" class="mycode"> <pre>class BoundedBuffer {<br /> final Lock lock = new ReentrantLock();<br /> final Condition notFull = lock.newCondition(); <br /> final Condition notEmpty = lock.newCondition(); final Object[] items = new Object[100]; int putptr, takeptr, count;<br /><br /> public void put(Object x) throws InterruptedException {<br /> lock.lock();<br /> try {<br /> while (count == items.length) <br /> notFull.await();<br /> items[putptr] = x; <br /> if (++putptr == items.length) putptr = 0;<br /> ++count;<br /> notEmpty.signal();<br /> } finally {<br /> lock.unlock();<br /> }<br /> }<br /> public Object take() throws InterruptedException {<br /> lock.lock();<br /> try {<br /> while (count == 0) <br /> notEmpty.await();<br /> Object x = items[takeptr]; <br /> if (++takeptr == items.length) takeptr = 0;<br /> --count;<br /> notFull.signal();<br /> return x;<br /> } finally {<br /> lock.unlock();<br /> }<br /> } <br />}</pre> </div> 具体的说明请参考JDK 1.5的文档?br />5. 除了用lock和await-and-signal来代替synchronized和wait-and-notify外,其语义和机制基本一栗await()在进入前也会自动释放锁,然后再返回前重新获得锁;<br />6. 使用Condition Variables的原因:<br />  1) 如果使用Lock对象Q则必须使用condition variablesQ?br />  2) 每个Lock对象可以创徏多个condition variable.<img src ="http://www.tkk7.com/evanwhj/aggbug/33938.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/evanwhj/" target="_blank">Evan</a> 2006-03-06 22:21 <a href="http://www.tkk7.com/evanwhj/archive/2006/03/06/33938.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>多线E?4)QJTW?章笔?/title><link>http://www.tkk7.com/evanwhj/archive/2006/03/05/33768.html</link><dc:creator>Evan</dc:creator><author>Evan</author><pubDate>Sun, 05 Mar 2006 15:25:00 GMT</pubDate><guid>http://www.tkk7.com/evanwhj/archive/2006/03/05/33768.html</guid><wfw:comment>http://www.tkk7.com/evanwhj/comments/33768.html</wfw:comment><comments>http://www.tkk7.com/evanwhj/archive/2006/03/05/33768.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/evanwhj/comments/commentRss/33768.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/evanwhj/services/trackbacks/33768.html</trackback:ping><description><![CDATA[<h3>Chapter 3. Data synchronization</h3> ?a >W二?/a>中介l了如何创徏U程对象、启动和l止U程。但多线E编E的关键在于多个U程之间数据的共享和同步Q从q一章开始,详l介l线E之间数据的׃n和同步的各种Ҏ(gu)?br /><br /> <strong>3.1 The Synchronized Keywor</strong> <br />1. synchronized是Java中最基本也最常用的用来编写多U程安全代码的关键字Q用以保护对多线E共享的数据的操作L完整的;<br /> 2. <strong>Atomic</strong>: 当一个操作被定义成原子操作时Q意味着该操作在执行q程中不会被打断Q原子操作可以由g保证或者通过软g来模拟;<br /> 3. <strong>Mutex Lock</strong>: 在很多多U程pȝQ通过互斥锁来保护的共享数据。Java中的M一个对象都有一个与之相关的锁,当一个方法被声明成synchronizedӞpC当U程q入该方法前Q必获得相应对象的锁,在执行完毕再释放q个锁。从而保证同一时刻只有一个线E调用该对象上的被声明ؓsynchronized的方法。注意:Java的互斥锁只能加在对象U上Q获得某个对象的锁,q不能保证该对象的属性和其它非synchronized的方法是U程安全的;也不能保证受保护的方法里调用的其它对象是多线E安全的Q除非Q何调用这些没有被保护的方法或者对象只通过受保护的Ҏ(gu)q行调用。所以,~写U程安全的代码关键就在于规划Ҏ(gu)和对象之间的调用关系Qƈ量采用相同对象的锁来进行同步控制?br /> <br /> <strong>3.2 The Volatile Keyword</strong> <br />1. Scope of a Lock: 锁的作用范围卌得和释放锁之间的那段旉?br /> 2. Java标准虽然声明存取一个非long和double变量的操作是原子操作Q但׃不同虚拟机实现的差异Q在多线E环境下每个U程可能会保留自q工作拯Q而导致变量的g生冲H。ؓ了避免这U情늚发生Q可以有两种Ҏ(gu)Q?br />   1) 为变量创建声明ؓsynchronized的setter和getterҎ(gu)Q然后Q何调用(包括在类c部Q该变量的地斚w通过setter和getterҎ(gu)Q?br />   2) 采用volatile声明Q确保每ơ存取这些属性时都从d存中d或者写入主内存中;<br />   3) volatile仅仅用于解决Java内存模式D的问题,只能q用在对该变量只做一个单一装蝲或写入操作且该方法的其它操作q不依赖该变量的变化。如Q在一个@环体中作为递增或递减变量时就不能使用volatile来解决线E同步的问题?br /> 3. volatile的用是有限的,一般而言Q仅仅将其作为强制虚拟机L从主内存d变量的一个手D,或者某些需要其参数声明为volatile的函数?<br /><br /><strong>3.3 More on Race Conditions</strong> <br />本节以打字游戏中昄成W的例子来解释了可能存在的race condition。关键要注意以下几点Q?br /> 1. 操作pȝ会随机的切换多个U程的运行,因此当多个线E调用同一个方法时Q可能在<em style="color: rgb(255, 0, 0);"><strong>M地方</strong></em>被暂停而将控制权交l另外的U程Q?br /> 2. Z减少被误用的可能QL假设Ҏ(gu)有可能被多个U程调用Q?br /> 3. 锁仅仅与某个特定实例相关Q而与MҎ(gu)和类都无养Iq一点当需要存取类属性或Ҏ(gu)时要特别注意Q?br /> 4. M时候只有一个线E能够运行某个类中一个被声明为synchronized的静态方法;一个线E只能运行某个特定实例中一个被声明为synchronized的非静态方法?br /> <br /> <strong>3.4 Explicit Locking</strong> <br />1. 学过Win32下编写多U程的朋友刚开始可能会被Java的Synchronized关键词搞p涂。因为Java中的M一个对象都有一个与之相关的锁,而不象在Win32下要先定义一个互斥量Q然后再调用一个函数进入或者离开互斥区域。在JDK 1.5以后也开始提供这U显C声明的锁。JDK 1.5中定义了一个Lock接口和一些类Q允许程序员昄的用锁对象?br />2. 在Lock接口里有两个Ҏ(gu)Qlock()和unlock()用来获取和释N对象Q从而保证受保护的代码区域是U程安全的?br />3. 使用锁对象的一个好处在于可以被保存、传递和抛弃Q以在比较复杂的多线E应用中使用l一的锁?br /> 在用锁对象ӞLlock()和unlock()调用包含在try/finally块中Q以防止q行时异常的抛出而导致死锁的情况?br /> <br /> <strong>3.5 Lock Scope</strong> <br />利用lock()和unlock()Ҏ(gu)Q我们可以在M地方使用它们Q从一行代码到跨越多个Ҏ(gu)和对象,q样pҎ(gu)E序设计需要来定义锁的作用(scope of lock)范围Q而不是象以前局限在对象的层ơ上?<strong><br /><br />3.5.1 Synchronized Blocks</strong><br /> 1. 利用synchronized关键字也能徏立同步块Q而不一定非得同步整个方法?br /> 2. 同步一D代码时Q需要明的指定获取哪个对象的锁(q就cM于锁对象?Q这P可以在多个Ҏ(gu)或对象中׃nq个锁对象?br /> <br /> <strong>3.6 Choosing a Locking Mechanism</strong> <br />使用锁对象还是同步关键字(synchronized)Q这个取决于开发员自己。用synchronized比较单,但相对而言Q比较隐晦,在比较复杂的情况?如要同时同步静态和非静态方法时)Q没有锁对象来得直观和统一。一般而言Qsynchronized单,易于使用Q但同时相对而言效率较低Q且不能跨越多个Ҏ(gu)?br /><br /> <strong>3.6.1 The Lock Interface</strong><br /> <div id="xulvfil" class="mycode"> <pre>public interface Lock {<br /> void lock();<br /> void lockInterruptibly() throws InterruptedException;<br /> boolean tryLock();<br /> boolean tryLock(long time, TimeUnit unit)<br /> throws InterruptedException;<br /> void unlock();<br /> Condition newCondition(); <br />}</pre> </div> 其中的tryLock()和tryLock(long, TimeUnit)尝试获取锁对象Q如果不能获取或在指定时间内不能获取Q将立即q回。调用者可以根据返回值来判断是否获得了锁对象以做q一步的操作?br /> <br /> <strong>3.7 Nested Locks</strong> <br />1. 在一个同步方法内调用同一个对象上的另外的同步Ҏ(gu)的情况,UC为嵌套锁(nested locking)。系l将自动执行嵌套的同步方法,而无ȝ待锁的释放。因此,有的时候,即一些私有方法仅仅被已同步的Ҏ(gu)调用Q我们也l其加上synchronized关键字,以减后l维护时可能产生的误对{?br /> 2. ReenterantLockcM支持嵌套锁。在ReenterantLockcȝ持一个计数器Q只有当q个计数器ؓ0Ӟ才会释放锁。注意:<strong>q个Ҏ(gu)是ReenterantLockcȝҎ(gu),而不是所有实现Lock接口的类的特性?/strong><br /> 3. 需要支持嵌套锁的一个原因是Ҏ(gu)之间交叉调用(cross-calling)。设惛_象a的方法M1调用对象b的方法N1Q然后N1再调用对象a的方法M2Q而M1和M2都是同步Ҏ(gu)Q如果不支持嵌套锁,则N1在调用M2时等待M1释放锁,而M1则由于N1没有q回永远也不会释NQ这样就产生了死锁?br /> 4. synchronized和Lock接口q没有提供锁对象被嵌套获取的ơ数Q但ReentrantLock则提供了q样一U机Ӟ<br /> <div id="dgbhnjm" class="mycode"> <pre>public class ReentrantLock implements Lock {<br /> public int getHoldCount();<br /> public boolean isLocked();<br /> public boolean isHeldByCurrentThread();<br /> public int getQueueLength();<br /> ... <br />}</pre> </div> 其中Q?br />     1) getHoldCount()q回当前U程的获取次敎ͼq回0q不表示该锁是可获取的,有可能没有被当前U程获得Q?br />     2) isLocked()判断该锁对象是否被Q何线E获得;<br />     3) isHeldByCurrentThread()判断是否由当前线E获得;<br />     4) getQueueLength()用来估计当前有多线E在{待获取q个锁对象?br /> <br /> <strong>3.8 Deadlock</strong> <br />介绍了死锁的概念Qƈ修改例子代码来演Cdeadlock的生。死锁一般生在多个U程在多个锁上同步时产生的;当然Q多个线E在判断多个条g的时候,也有可能产生死锁?br /> <br /> <strong>3.9 Lock Fairness</strong> <br />1. Java里锁的获取机制依赖于底层多线E系l的实现Qƈ不保证一个特定的序Q?br /> 2. ReentrantLockcL供一个先q先?first-in-first-out)的获取锁的选项(在创建锁对象时传入true??img width="1" height="1" src="http://blog.csdn.net/evanwhj/aggbug/616068.aspx" alt="" /><br />文章来源:<a >http://blog.csdn.net/evanwhj/archive/2006/03/05/616068.aspx</a><img src ="http://www.tkk7.com/evanwhj/aggbug/33768.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/evanwhj/" target="_blank">Evan</a> 2006-03-05 23:25 <a href="http://www.tkk7.com/evanwhj/archive/2006/03/05/33768.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>多线E?3)QJTW?章笔?/title><link>http://www.tkk7.com/evanwhj/archive/2006/03/05/33769.html</link><dc:creator>Evan</dc:creator><author>Evan</author><pubDate>Sun, 05 Mar 2006 15:25:00 GMT</pubDate><guid>http://www.tkk7.com/evanwhj/archive/2006/03/05/33769.html</guid><wfw:comment>http://www.tkk7.com/evanwhj/comments/33769.html</wfw:comment><comments>http://www.tkk7.com/evanwhj/archive/2006/03/05/33769.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/evanwhj/comments/commentRss/33769.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/evanwhj/services/trackbacks/33769.html</trackback:ping><description><![CDATA[<p><span style="font-size: 120%;"><strong>Chapter2: Thread Creation and Management</strong></span></p> <p><strong>2.1 What Is a Thread? </strong></p> <p>介绍了什么是U程Q以及线E?thread, multithread)与进E?process, mutltitask)的区别。其中的一个重要区别是对共享数据的讉K。进E可以共享操作系l别的某些数据区域Q如剪脓(chung)板;而线E是对程序自有的数据q行׃n。进E之间对׃n数据的存取方法是Ҏ(gu)的,因此自然能够得到E序员的注意Q而线E之间对׃n数据的存取与对线E自q数据的存取方法是一L(fng)Q所以常常比较隐蔽,而被E序员忽略。其实,q也是多U程开发比较难的地斏V所以,q一节最后说Q?quot;<em style="color: rgb(255, 0, 0);"><strong>A thread, then, is a discrete task that operates on data shared with other threads.</strong></em>Q线E就是一个在与其它线E共享的数据上进行操作的单独d。)"<br /><br /> <strong>2.2 Creating a Thread</strong> </p> <p>1. 有两U方法创建线E:使用ThreadcL者Runnable接口 <br />2. CZE序竟然是编一个打字游戏,所以,q本书的门槛q是有点高的:(。当然可以从该书的站点直接下?a >代码</a>?</p> 3. Thread class<br /> <div style="border: 1px dotted blue; padding: 10px; width: 100%; background-color: rgb(192, 192, 192); font-size: 80%; overflow-x: auto;"> <pre><font size="2">package java.lang;<br />public class Thread implements Runnable {<br /> public Thread( );<br /> public Thread(Runnable target);<br /> public Thread(ThreadGroup group, Runnable target);<br /> public Thread(String name);<br /> public Thread(ThreadGroup group, String name);<br /> public Thread(Runnable target, String name);<br /> public Thread(ThreadGroup group, Runnable target, String name);<br /> public Thread(ThreadGroup group, Runnable target, String name,<br /> long stackSize);<br /> public void start( );<br /> public void run( ); <br />}</font></pre> </div> <strong>Thread name</strong>: U程名,用以打印U程信息时用Q缺省ؓThread-N?<br /><strong>Runnable target</strong>Q可q行的目标。一个可q行的对象就是一串可qE执行的指o。缺省就是在run()Ҏ(gu)中编写的内容?<br /><strong>Thread group</strong>Q线E组。对于大多数应用来说没什么意义,~省在同一l?<br /><strong>Stack size</strong>Q线E堆栈大,与^台相兟뀂ؓ了ɽE序更具可移植性,q不推荐使用?br /><br /><strong>2.3 The Lifecycle of a Thread </strong> <p> </p> <p dir="ltr">1. Creating a ThreadQ创Z个线E对象,q没有开始执行一个线E?<br />2. Starting a ThreadQ在调用U程对象的start()Ҏ(gu)前,一直处于等待状态。可以通过调用isAlive()Ҏ(gu)来获取线E是否正在运行; <br />3. Terminating a ThreadQ线E在以下情况下结束  <br />  1)执行完run()中的语句Q?br />  2)抛出一个异常,包括其没有捕L(fng)异常Q?br />  3)其所在的E序Q或者容器)调用System.exit()?<br /><span style="font-weight: bold; color: red;">注意Q一个线E结束后Q就不能再次启动Q该U程变成一个普通的对象Q如果试囑ֆơ调用start()Ҏ(gu)Q将抛出java.lang.IllegalThreadStateException异常。如果想多次q行Q要么创建新的对象;要么是不要l束该线E?/span><br /> 4. Javaq没有提供可靠的Ҏ(gu)来暂停、挂h者重启一个线E的Ҏ(gu)Q线E本w能通过sleep()函数来暂停执行。目前依然只能确保若q毫U别的_ֺ?<br />5. Thread CleanupQ线E终止后Q线E对象依然存在。可以通过join()Ҏ(gu)以阻塞方?blocked)来等待某个线E终止?br /><br /><strong>2.4 Two Approches to Stop a Thread</strong> </p> <p dir="ltr">1. <strong>Setting a Flag</strong>Q在U程的执行过E中判断其它U程是否标志置位。其~点是有旉延迟Q尤其是当进入了某些被阻塞的函数如:sleep(), wait(){; <br />2. <strong>调用U程的interrupt()Ҏ(gu)</strong>Q线E的执行q程中改为判断isInterrupted()的返回倹{可以解决线E进入阻塞导致的延迟Q但依然解决不了长旉计算而导致的延迟。interrupt()有两个作用:1)l止sleep()和wait()Q抛出InterruptedExceptionQ?)使isInterrupted()q回true。下面这D代码将演示interrupt()的作用:</p> <div style="border: 1px dotted rgb(0, 0, 255); overflow-x: auto; width: 100%; background-color: rgb(192, 192, 192);"> <pre><font size="2">public class TestInterrupted {<br /> public static void main(String args[]) throws InterruptedException{<br /> Foo foo = new Foo();<br /> foo.start();<br /> Thread.currentThread().sleep(100); //注释掉这句有什么媄响呢Q?br /> System.out.println("before interrupt");<br /> foo.interrupt();<br /> System.out.println("after interrupt");<br /> } } <br /><br />class Foo extends Thread {<br /> public void run() {<br /> try{<br /> while(!isInterrupted()) {<br /> System.out.println("start calculating...");<br /> double pi = 3.1415926;<br /> for(int i=0; i<5; i++) {<br /> for(long j=0; j<1000000; j++) {<br /> pi *= pi;<br /> }<br /> System.out.println("i="+i);<br /> }<br /> System.out.println("before sleep");<br /> sleep(5000); //注释掉这句及相关的try...catch语句Q又怎样呢?<br /> System.out.println("after sleep");<br /> }<br /> } catch(InterruptedException ex) {<br /> ex.printStackTrace(System.out);<br /> }<br /> }<br />}</font></pre> </div> <p dir="ltr"><strong></strong> </p> <p dir="ltr"><strong>2.5 The Runnable Interface </strong></p> <p dir="ltr">Z么有了Threadc,q要有Runnable接口呢?最主要的原因是Z解决Java不能多重l承的问题。线E承自ThreadQ还是仅仅实现Runnable接口Q取决于q个U程的作用。不q,如果仅仅实现Runnable接口Q则在线E里不能使用ThreadcȝҎ(gu)Q比如interrupt()和isInterrupted()。当Ӟq个q是要取决于实际情况?br /><br /><strong>2.6 Threads and Objects</strong> </p> <p dir="ltr">主要讲解U程与对象的关系。线E根本上q是个对象,其可以存取Q何对象包括其它线E对象,当然也能被其它对象存取,只要没有因ؓ争夺公共资源而被锁定Q线E对象中的Q何属性和Ҏ(gu)都有可能同时执行。ƈ且Java中的锁只针对对象本nQƈ不包括对象下的属性;而对Ҏ(gu)同步Q则{同于对对象同步。更q一步的说明q可以参考《Practical Java》中?quot;实践46Q面对instance函数Qsynchronized锁定的是对象(object)而非函数(methods)或代码(codeQ?quot;。下面用两段代码来说明一下:<br /><strong>代码1:</strong></p> <div style="border: 1px dotted rgb(0, 0, 255); overflow-x: auto; width: 100%; background-color: rgb(192, 192, 192);"> <pre>public class TestLock {<br /> public static void main(String args[])<br /> throws InterruptedException{<br /> Foo foo = new Foo();<br /> foo.start();<br /> Thread t = Thread.currentThread();<br /> for(int i=0; i<10; i++) {<br /> foo.setInt2("Main", i, i+20);<br /> }<br /> }<br />}<br /><br />class Foo extends Thread{<br /> protected int arrI[] = new int[10];<br /><br /> public void run() {<br /> try {<br /> for(int i=0; i<10; i++) { <br /> setInt("Foo", i, i); <br /> } <br /> } catch(InterruptedException ex) {}<br /> } <br /><br /> public synchronized void setInt(String from, int pos, int val)<br /> throws InterruptedException{<br /> arrI[pos] = val;<br /> sleep((long)(Math.random()*5000));<br /> System.out.println(from+":arrI["+pos+"]="+arrI[pos]);<br /> }<br /><br /> public void setInt2(String from, int pos, int val)<br /> throws InterruptedException {<br /> synchronized(arrI){<br /> arrI[pos] = val;<br /> sleep((long)(Math.random()*5000));<br /> System.out.println(from+":arrI["+pos+"]="+arrI[pos]);<br /> }<br /> } <br />}</pre> </div> l果Q非U程安全QsetInt()在对象上加锁Q而setInt2()在属性arrI上加锁,不同的锁不能保证U程安全。可能的l果如下Q?br /> <div style="border: 1px dotted rgb(128, 128, 128); overflow-x: auto; width: 100%; color: rgb(255, 255, 255); background-color: rgb(0, 0, 0);"> <pre>Foo:arrI[0]=0 <br />Main:arrI[0]=0 <br />Main:arrI[1]=21 <br />Main:arrI[2]=22 <br />Foo:arrI[1]=21 <br />Main:arrI[3]=23 <br />Main:arrI[4]=24 <br />Main:arrI[5]=25 <br />Foo:arrI[2]=2 <br />Main:arrI[6]=26 <br />Main:arrI[7]=27 <br />Foo:arrI[3]=3 <br />Foo:arrI[4]=4 <br />Main:arrI[8]=28 <br />Main:arrI[9]=29 <br />Foo:arrI[5]=5 <br />Foo:arrI[6]=6 <br />Foo:arrI[7]=7 <br />Foo:arrI[8]=8 <br />Foo:arrI[9]=9</pre> </div> <strong><br />代码2:</strong> <div style="border: 1px dotted rgb(0, 0, 255); overflow-x: auto; width: 100%; background-color: rgb(192, 192, 192);"> <pre>public class TestLock1 {<br /> public static void main(String args[])<br /> throws InterruptedException{<br /> Foo1 foo = new Foo1();<br /> foo.start();<br /> Thread t = Thread.currentThread();<br /> for(int i=0; i<10; i++) {<br /> foo.setInt2("Main", i, i+20);<br /> }<br /> } <br />} <br /><br />class Foo1 extends Thread{<br /> protected int arrI[] = new int[10];<br /><br /> public void run() {<br /> try{ <br /> for(int i=0; i<10; i++) { <br /> setInt("Foo", i, i); <br /> } <br /> }catch(InterruptedException ex){} <br /> }<br /><br /> public synchronized void setInt(String from, int pos, int val)<br /> throws InterruptedException{<br /> arrI[pos] = val;<br /> sleep((long)(Math.random()*5000));<br /> System.out.println(from+":arrI["+pos+"]="+arrI[pos]);<br /> }<br /><br /> public synchronized void setInt2(String from, int pos, int val)<br /> throws InterruptedException{<br /> arrI[pos] = val;<br /> sleep((long)(Math.random()*5000));<br /> System.out.println(from+":arrI["+pos+"]="+arrI[pos]);<br />  }<br />}</pre> </div> l果Q线E安?img width="1" height="1" src="http://blog.csdn.net/evanwhj/aggbug/616046.aspx" alt="" /><a ><br /></a><img src ="http://www.tkk7.com/evanwhj/aggbug/33769.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/evanwhj/" target="_blank">Evan</a> 2006-03-05 23:25 <a href="http://www.tkk7.com/evanwhj/archive/2006/03/05/33769.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>多线E?2)QJ2SE 5.0多线E增强简?/title><link>http://www.tkk7.com/evanwhj/archive/2006/03/05/33770.html</link><dc:creator>Evan</dc:creator><author>Evan</author><pubDate>Sun, 05 Mar 2006 15:25:00 GMT</pubDate><guid>http://www.tkk7.com/evanwhj/archive/2006/03/05/33770.html</guid><wfw:comment>http://www.tkk7.com/evanwhj/comments/33770.html</wfw:comment><comments>http://www.tkk7.com/evanwhj/archive/2006/03/05/33770.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/evanwhj/comments/commentRss/33770.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/evanwhj/services/trackbacks/33770.html</trackback:ping><description><![CDATA[J2SE 5.0在多U程上做了很大的改进Q提供了更多的APIQ包括:<br /> <strong>Atomic variables:</strong> A set of classes that provide threadsafe operations without synchronization<br /> <strong>Explicit locks: </strong>Synchronization locks that can be acquired and released programmatically<br /> <strong>Condition variables:</strong> Variables that can be the subject of a targeted notification when certain conditions exist<br /> <strong>Queues:</strong> Collection classes that are thread-aware <strong>Synchronization primitives:</strong> New classes that perform complex types of synchronization<br /> <strong>Thread pools:</strong> Classes that can manage a pool of threads to run certain tasks<br /> <strong>Thread schedulers:</strong> Classes that can execute tasks at a particular point in time<br /> <br /> 在《Java Threads》一书中其归纳Zc:<br /> 1. 对现有功能的新实玎ͼ<br /> 2. 提供了重要的多线E工P如线E池(pool)和计?schedule)Q?br /> 3. 最化同步工具(Minimal synchronization utilities)?br /> <br />q些功能的妙处我现在自然是无法体会得刎ͼ但对于JDK 5.0中提供的q些多线E工P会不会也遭遇JDK 1.4提供的Log API的命q,因敌不过W三方工兯成为摆讑֑Q至目前我q在用Log4JQ且其也没有停止开发的q象Q?<img width="1" height="1" src="http://blog.csdn.net/evanwhj/aggbug/616043.aspx" alt="" /><a ><br /></a><img src ="http://www.tkk7.com/evanwhj/aggbug/33770.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/evanwhj/" target="_blank">Evan</a> 2006-03-05 23:25 <a href="http://www.tkk7.com/evanwhj/archive/2006/03/05/33770.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>多线E?1): 选书http://www.tkk7.com/evanwhj/archive/2006/03/05/33771.htmlEvanEvanSun, 05 Mar 2006 15:25:00 GMThttp://www.tkk7.com/evanwhj/archive/2006/03/05/33771.htmlhttp://www.tkk7.com/evanwhj/comments/33771.htmlhttp://www.tkk7.com/evanwhj/archive/2006/03/05/33771.html#Feedback0http://www.tkk7.com/evanwhj/comments/commentRss/33771.htmlhttp://www.tkk7.com/evanwhj/services/trackbacks/33771.htmlM一门支持多U程的语a中,多线E是都是一个让人又爱又恨的东西。Java的多U程相对而言比其它语a要简单一点,如果不是开发框架类或者系l的程序,也许很少会碰到要明确到Java的多U程APIQ但事实上不{于你不用注意多U程安全的问题,其当你在开发WebE序的时候,在类中用了静态属性(static fieldsQ而不仅仅是对象属性(instance fieldsQ的时候,如果在压力测试或者提交给用户使用的时候,发生了一些不可重现的错误或者数据؜q时候,那往往要查查这些用了静态属性的cL否是多线E安全的了。当Ӟ如果你专注于开发Web应用Qƈ且很涉及框架或核心模块的开发,那也基本上知道synchronized的关键字的应用就可以了。这也许是Java多线E相对其它语a中多U程要简单一点的原因?/p> 当然Q这ơ我打算比较深入地来了解了解一下Java多线E开发的其它一些内容,那么找一本好的书是一个比 较好的开始。关于Java多线E开发的专著比较有名的大U是《Java Threads, 3rd Edition》和《Java Thread Programming》了Q前者基于JDK 1.5(q个版本对多U程q行了很大的改进)q行介绍Qƈ且指Z与以前版本的区别Q而后者出版于1999q_是基于JDK 1.2q行讲解的。所以呢Q基本上采用W一本ؓ丅R同时也参考一下《Practical Java》和《Effective Java》的相关条目?br />
q几本书的封面如下,相关书的介绍可去Amazon查看一下:




Evan 2006-03-05 23:25 发表评论
]]>
Java学习W记Q序ahttp://www.tkk7.com/evanwhj/archive/2006/03/05/33772.htmlEvanEvanSun, 05 Mar 2006 15:25:00 GMThttp://www.tkk7.com/evanwhj/archive/2006/03/05/33772.htmlhttp://www.tkk7.com/evanwhj/comments/33772.htmlhttp://www.tkk7.com/evanwhj/archive/2006/03/05/33772.html#Feedback0http://www.tkk7.com/evanwhj/comments/commentRss/33772.htmlhttp://www.tkk7.com/evanwhj/services/trackbacks/33772.html


Evan 2006-03-05 23:25 发表评论
]]>
վ֩ģ壺 ƷѾƷ| ѹۿ| ޸߲| ŵ| һ | þþþùAV鶹| ޽Сxxxx| ҹƵ߹ۿ| ޾ƷA߹ۿ| ˳ɵӰվ| žžƵ| ޳AVƬ| ܲƵ| ߹ۿվ| ˳ӰԺҹվ| ҹAëƬƵ | ҹһ| һëƬƬѹۿ| ҹҹAһ| Ʒ޾ƷþþƷ| ŷ޾ƷƵ߹ۿ| ༤ۺ͵ | Ʒmnbavվ | ۺС˵ͼƬͼ| **˹ëƬ| ͼƬ߹ۿ| GOGOGOѹۿ| VAۺVAVA| 96|| Ů18ëƬˮѲ| Ʒ߹ۿ| 91ƷѾþþþþþþ| ޾ѡ߹ۿ| 91Ʒ| AVרAV԰| þþþþþþþþѾƷ| ޾Ʒ99߹ۿ| Ůֻwwwվ| Ƶ| vavava| Ļ|