??xml version="1.0" encoding="utf-8" standalone="yes"?>理论在线观看,欧美电影一二区,国产精品视频九色pornhttp://www.aygfsteel.com/oracle/category/42070.html1100111010001110 1001010010001010zh-cnWed, 21 Oct 2009 07:06:33 GMTWed, 21 Oct 2009 07:06:33 GMT60实战体会Java多线E编E精?/title><link>http://www.aygfsteel.com/oracle/archive/2009/10/21/299116.html</link><dc:creator>逍遥晨空</dc:creator><author>逍遥晨空</author><pubDate>Tue, 20 Oct 2009 16:06:00 GMT</pubDate><guid>http://www.aygfsteel.com/oracle/archive/2009/10/21/299116.html</guid><wfw:comment>http://www.aygfsteel.com/oracle/comments/299116.html</wfw:comment><comments>http://www.aygfsteel.com/oracle/archive/2009/10/21/299116.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/oracle/comments/commentRss/299116.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/oracle/services/trackbacks/299116.html</trackback:ping><description><![CDATA[下面的这个简单的 Java E序完成四项不相关的d。这LE序有单个控制线E,控制在这四个d之间U性地Ud。此外,因ؓ所需的资?? 打印机、磁盘、数据库和显C屏 ?׃g和Y件的限制都有内在的潜伏时_所以每Q务都包含明显的等待时间。因此,E序在访问数据库之前必须{待打印机完成打印文件的dQ等{。如果您正在{待E序的完成,则这是对计算资源和您的时间的一U拙劣用。改q此E序的一U方法是使它成ؓ多线E的?br /> <br /> 四项不相关的d<br /> class myclass {<br /> static public void main(String args[]) {<br /> print_a_file();<br /> manipulate_another_file();<br /> access_database();<br /> draw_picture_on_screen();<br /> }<br /> }<br /> <br /> <br /> <br /> 多个q程<br /> <br /> 在大多数操作pȝ中都可以创徏多个q程。当一个程序启动时Q它可以为即开始的每项d创徏一个进E,q允许它们同时运行。当一个程序因{待|络讉K或用戯入而被dӞ另一个程序还可以q行Q这样就增加了资源利用率。但是,按照q种方式创徏每个q程要付Z定的代hQ设|一个进E要占用相当一部分处理器时间和内存资源。而且Q大多数操作pȝ不允许进E访问其他进E的内存I间。因此,q程间的通信很不方便Qƈ且也不会它自己提供l容易的~程模型?br /> <br /> U程<br /> <br /> U程也称型进E?(LWP)。因为线E只能在单个q程的作用域内活动,所以创建线E比创徏q程要廉价得多。这P因ؓU程允许协作和数据交换,q且在计资源方面非常廉P所以线E比q程更可取。线E需要操作系l的支持Q因此不是所有的机器都提供线E。Java ~程语言Q作为相当新的一U语aQ已线E支持与语言本n合ؓ一体,q样对U程提供了强健的支持?br /> <br /> 使用 Java ~程语言实现U程<br /> <br /> Java~程语言使多U程如此单有效,以致于某些程序员说它实际上是自然的。尽在 Java 中用线E比在其他语a中要Ҏ得多Q仍然有一些概念需要掌握。要C的一仉要的事情?main() 函数也是一个线E,q可用来做有用的工作。程序员只有在需要多个线E时才需要创建新的线E?br /> <br /> Thread c?br /> 下面的代码说明了它的用法Q?br /> <br /> 创徏两个新线E?br /> <br /> import java.util.*;<br /> class TimePrinter extends Thread {<br /> int pauseTime;<br /> String name;<br /> public TimePrinter(int x, String n) {<br /> pauseTime = x;<br /> name = n;<br /> }<br /> public void run() {<br /> while(true) {<br /> try {<br /> System.out.println(name + “:” + new<br /> Date(System.currentTimeMillis()));<br /> Thread.sleep(pauseTime);<br /> } catch(Exception e) {<br /> System.out.println(e);<br /> }<br /> }<br /> }<br /> static public void main(String args[]) {<br /> TimePrinter tp1 = new TimePrinter(1000, “Fast Guy”);<br /> tp1.start();<br /> TimePrinter tp2 = new TimePrinter(3000, “Slow Guy”);<br /> tp2.start();<br /> }<br /> }<br /> <br /> 在本例中Q我们可以看C个简单的E序Q它按两个不同的旉间隔(1 U和 3 U?在屏q上昄当前旉。这是通过创徏两个新线E来完成的,包括 main() ׃个线E。但是,因ؓ有时要作为线E运行的cd能已l是某个cdơ的一部分Q所以就不能再按q种机制创徏U程。虽然在同一个类中可以实CQ意数量的接口Q但 Java ~程语言只允怸个类有一个父cR同Ӟ某些E序员避免从 Thread cd出,因ؓ它强加了cdơ。对于这U情况,p runnable 接口?br /> Runnable 接口<br /> <br /> 此接口只有一个函敎ͼrun()Q此函数必须由实C此接口的cd现。但是,p行这个类而论Q其语义与前一个示例稍有不同。我们可以用 runnable 接口改写前一个示例?不同的部分用黑体表示?<br /> <br /> 创徏两个新线E而不强加cd?br /> import java.util.*;<br /> class TimePrinter implements Runnable {<br /> int pauseTime;<br /> String name;<br /> public TimePrinter(int x, String n) {<br /> pauseTime = x;<br /> name = n;<br /> }<br /> public void run() {<br /> while(true) {<br /> try {<br /> System.out.println(name + “:” + new<br /> Date(System.currentTimeMillis()));<br /> Thread.sleep(pauseTime);<br /> } catch(Exception e) {<br /> System.out.println(e);<br /> }<br /> }<br /> }<br /> static public void main(String args[]) {<br /> Thread t1 = new Thread(new TimePrinter(1000, “Fast Guy”));<br /> t1.start();<br /> Thread t2 = new Thread(new TimePrinter(3000, “Slow Guy”));<br /> t2.start();<br /> }<br /> }<br /> h意,当?runnable 接口Ӟ您不能直接创建所需cȝ对象q运行它; 必须?Thread cȝ一个实例内部运行它。许多程序员更喜?runnable 接口Q因Z Thread cȝ承会强加cdơ?br /> <br /> synchronized 关键?br /> <br /> 到目前ؓ止,我们看到的示例都只是以非常简单的方式来利用线E。只有最的数据,而且不会出现两个U程讉K同一个对象的情况。但是,在大多数有用的程序中Q线E之间通常有信息流。试考虑一个金融应用程序,它有一?Account 对象Q如下例中所C:<br /> <br /> 一个银行中的多Ҏ?br /> <br /> public class Account {<br /> String holderName;<br /> float amount;<br /> public Account(String name, float amt) {<br /> holderName = name;<br /> amount = amt;<br /> }<br /> public void deposit(float amt) {<br /> amount += amt;<br /> }<br /> public void withdraw(float amt) {<br /> amount -= amt;<br /> }<br /> public float checkBalance() {<br /> return amount;<br /> }<br /> }<br /> 在此代码样例中潜伏着一个错误。如果此cȝ于单U程应用E序Q不会有M问题。但是,在多U程应用E序的情况中Q不同的U程有可能同时讉K同一?Account 对象Q比如说一个联合帐L所有者在不同?ATM 上同时进行访问。在q种情况下,存入和支出就可能以这L方式发生Q一个事务被另一个事务覆盖。这U情况将是灾难性的。但是,Java ~程语言提供了一U简单的机制来防止发生这U覆盖。每个对象在q行旉有一个关联的锁。这个锁可通过为方法添加关键字 synchronized 来获得。这P修订q的 Account 对象(如下所C?不会遭受像数据损坏q样的错误:<br /> <br /> 对一个银行中的多Ҏ动进行同步处?br /> <br /> public class Account {<br /> String holderName;<br /> float amount;<br /> public Account(String name, float amt) {<br /> holderName = name;<br /> amount = amt;<br /> }<br /> public synchronized void deposit(float amt) {<br /> amount += amt;<br /> }<br /> public synchronized void withdraw(float amt) {<br /> amount -= amt;<br /> }<br /> public float checkBalance() {<br /> return amount;<br /> }<br /> }<br /> <br /> deposit() ?withdraw() 函数都需要这个锁来进行操作,所以当一个函数运行时Q另一个函数就被阻塞。请注意Q?checkBalance() 未作更改Q它严格是一个读函数。因?checkBalance() 未作同步处理Q所以Q何其他方法都不会d它,它也不会dM其他ҎQ不那些方法是否进行了同步处理?br /> <br /> Java ~程语言中的高多线E支?br /> U程l?br /> <br /> U程是被个别创徏的,但可以将它们归类到线E组中,以便于调试和监视。只能在创徏U程的同时将它与一个线E组相关联。在使用大量U程的程序中Q用线E组l织U程可能很有帮助。可以将它们看作是计机上的目录和文件结构?br /> <br /> U程间发?br /> <br /> 当线E在l箋执行前需要等待一个条件时Q仅?synchronized 关键字是不够的。虽?synchronized 关键字阻止ƈ发更C个对象,但它没有实现U程间发信。Object cMؓ此提供了三个函数Qwait()、notify() ?notifyAll()。以全球气候预程序ؓ例。这些程序通过地球分多单元,在每个@环中Q每个单元的计算都是隔离q行的,直到q些D于稳定,然后盔R单元之间׃交换一些数据。所以,从本质上Ԍ在每个@环中各个U程都必ȝ待所有线E完成各自的d以后才能q入下一个@环。这个模型称为屏蔽同步,下例说明了这个模型:<br /> <br /> 屏蔽同步<br /> public class BSync {<br /> int totalThreads;<br /> int currentThreads;<br /> public BSync(int x) {<br /> totalThreads = x;<br /> currentThreads = 0;<br /> }<br /> public synchronized void waitForAll() {<br /> currentThreads++;<br /> if(currentThreads < totalThreads) {<br /> try {<br /> wait();<br /> } catch (Exception e) {}<br /> }<br /> else {<br /> currentThreads = 0;<br /> notifyAll();<br /> }<br /> }<br /> }<br /> <br /> 当对一个线E调?wait() Ӟ该线E就被有效阻塞,只到另一个线E对同一个对象调?notify() ?notifyAll() 为止。因此,在前一个示例中Q不同的U程在完成它们的工作以后调?waitForAll() 函数Q最后一个线E将触发 notifyAll() 函数Q该函数释放所有的U程。第三个函数 notify() 只通知一个正在等待的U程Q当Ҏơ只能由一个线E用的资源q行讉K限制Ӟq个函数很有用。但是,不可能预知哪个线E会获得q个通知Q因取决?Java 虚拟?(JVM) 调度法?br /> <br /> ?CPU 让给另一个线E?br /> <br /> 当线E放弃某个稀有的资源(如数据库q接或网l端?Ӟ它可能调?yield() 函数临时降低自己的优先Q以便某个其他线E能够运行?br /> <br /> 守护U程<br /> <br /> 有两cȝE:用户U程和守护线E。用LE是那些完成有用工作的线E?守护U程是那些仅提供辅助功能的线E。Thread cL供了 setDaemon() 函数。Java E序运行到所有用LE终止,然后它将破坏所有的守护U程。在 Java 虚拟?(JVM) 中,即?main l束以后Q如果另一个用LE仍在运行,则程序仍然可以l运行?br /> <br /> 避免不提倡用的Ҏ<br /> 不提倡用的Ҏ是ؓ支持向后兼容性而保留的那些ҎQ它们在以后的版本中可能出现Q也可能不出现。Java 多线E支持在版本 1.1 和版?1.2 中做了重大修订,stop()、suspend() ?resume() 函数已不提倡用。这些函数在 JVM 中可能引入微妙的错误。虽然函数名可能听v来很׃hQ但h制诱惑不要用它们?br /> <br /> 调试U程化的E序<br /> <br /> 在线E化的程序中Q可能发生的某些常见而讨厌的情况是死锁、活锁、内存损坏和资源耗尽?br /> <br /> 死锁<br /> <br /> 死锁可能是多U程E序最常见的问题。当一个线E需要一个资源而另一个线E持有该资源的锁Ӟ׃发生死锁。这U情况通常很难。但是,解决Ҏ却相当好Q在所有的U程中按相同的次序获取所有资源锁。例如,如果有四个资??A、B、C ?D ? q且一个线E可能要获取四个资源中Q何一个资源的锁,则请保在获取对 B 的锁之前首先获取?A 的锁Q依此类推。如?#8220;U程 1”希望获取?B ?C 的锁Q?#8220;U程 2”获取?A、C ?D 的锁Q则q一技术可能导致阻塞,但它永远不会在这四个锁上造成死锁?br /> <br /> z锁<br /> <br /> 当一个线E忙于接受新d以致它永q没有机会完成Q何Q务时Q就会发生活锁。这个线E最l将出~冲区ƈDE序崩溃。试想一个秘书需要录入一信Q但她一直在忙于接电话,所以这信永远不会被录入?br /> <br /> 内存损坏<br /> <br /> 如果明智C?synchronized 关键字,则完全可以避免内存错误这U气Mh的问题?br /> <br /> 资源耗尽<br /> <br /> 某些pȝ资源是有限的Q如文g描述W。多U程E序可能耗尽资源Q因为每个线E都可能希望有一个这L资源。如果线E数相当大,或者某个资源的侯选线E数q远过了可用的资源敎ͼ则最好用资源池。一个最好的CZ是数据库q接池。只要线E需要用一个数据库q接Q它׃池中取出一个,使用以后再将它返回池中。资源池也称?资源库?br /> <br /> 调试大量的线E?br /> <br /> 有时一个程序因为有大量的线E在q行而极难调试。在q种情况下,下面的这个类可能会派上用场:<br /> <br /> public class Probe extends Thread {<br /> public Probe() {}<br /> public void run() {<br /> while(true) {<br /> Thread[] x = new Thread[100];<br /> Thread.enumerate(x);<br /> for(int i=0; i<100; i++) {<br /> Thread t = x[i];<br /> if(t == null)<br /> break;<br /> else<br /> System.out.println(t.getName() + “\t” + t.getPriority()<br /> + “\t” + t.isAlive() + “\t” + t.isDaemon());<br /> }<br /> }<br /> }<br /> }<br /> <br /> 限制U程优先U和调度<br /> <br /> Java U程模型涉及可以动态更改的U程优先U。本质上Q线E的优先U是?1 ?10 之间的一个数字,数字大表明d紧急。JVM 标准首先调用优先U较高的U程Q然后才调用优先U较低的U程。但是,该标准对h相同优先U的U程的处理是随机的。如何处理这些线E取决于基层的操作系l策略。在某些情况下,优先U相同的U程分时q行; 在另一些情况下Q线E将一直运行到l束。请CQJava 支持 10 个优先Q基层操作系l支持的优先U可能要得多,q样会造成一些؜乱。因此,只能优先作ؓ一U很_略的工具用。最后的控制可以通过明智C?yield() 函数来完成。通常情况下,请不要依靠线E优先来控制线E的状态? <img src ="http://www.aygfsteel.com/oracle/aggbug/299116.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/oracle/" target="_blank">逍遥晨空</a> 2009-10-21 00:06 <a href="http://www.aygfsteel.com/oracle/archive/2009/10/21/299116.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <footer> <div class="friendship-link"> <a href="http://www.aygfsteel.com/" title="狠狠久久亚洲欧美专区_中文字幕亚洲综合久久202_国产精品亚洲第五区在线_日本免费网站视频">狠狠久久亚洲欧美专区_中文字幕亚洲综合久久202_国产精品亚洲第五区在线_日本免费网站视频</a> </div> </footer> վ֩ģ壺 <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">֦</a>| <a href="http://" target="_blank">Ҧ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ӳ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ʡ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">̨ǰ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">Ž</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ƽ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ľ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ʢ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">Դ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">Ļ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ʯ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body>