快速业务通道

线程基础(第二部分)Java线程的缺陷和副作用几解决办法 - 编程入门网

作者 佚名技术 来源 NET编程 浏览 发布时间 2012-06-23
PI调用。

Join

如果一个应用程序需要执行很多时间,比如一个耗时很长的计算工作,你可以把该计算工作设计成线程。但是,假定还有另外一个线程需要计算结果,当计算结果出来后,如何让那个线程知道计算结果呢?解决该问题的一个方法是让第二个线程一直不停地检查一些变量的状态,直到这些变量的状态发生改变。这样的方式在UNIX风格的服务器中常常用到。Java提供了一个更加简单的机制,即线程类中的join 方法。

join 方法使得一个线程等待另外一个线程的结束。例如,一个GUI (或者其他线程)使用join方法等待一个子线程执行完毕:

CompleteCalcThread t = new

CompleteCalcThread();

t.start();

//

// 做一会儿其他的事情

// 然后等待

t.join();

// 使用计算结果...

你可以看到,用对子线程使用join方法,等待子线程执行完毕。 Join 有三种格式:

void join(): 等待线程执行完毕。

void join(long timeout): 最多等待某段时间让线程完成。

void join(long milliseconds, int nanoseconds): 最多等待某段时间(毫秒+纳秒),让线程完成。

线程API isAlive同join相关联时,是很有用的。一个线程在start(此时run方法已经启动)之后,在stop之前的某时刻处于isAlive 状态。

对于编写线程的程序员来说,还有其他两个有用的线程API,即wait和 notify。使用这两个API,我们可以精确地控制线程的执行过程。考虑一个简单的例子,有个生产者线程和消费者线程,为了让应用程序更有效率,所以我们不打算采用查询等待的方法。当消费者可以消费对象时,消费者需要得知该信息。

我们可以把该例子阐述如下:生产者线程不断地在运行着,把项目放入列表中,该列表的add方法由synchronize 关键字保护着,当一个对象添加到列表中,生产者就可以通知消费者:它已经添加一个对象,消费者可以消费该对象了。每个对象的run方法的伪代码请见表A。

表A: 演示高级线程方法的伪代码

class ProdCons { class List { public synchronized boolean add(Object o) {...} public synchronized boleanremove (Object o) {...} } List data = new List(); ProdThread producer = null; ConsThread consumer = null; ProdCons() { producer = new ProdThread(this); consumer = new ConsThread(this); producer.start(); consumer.start(); } }

线程基础(第二部分)Java线程的缺陷和副作用几解决办法(3)

时间:2010-12-08

消费者和生产者的类,请见表B和表C。

表B: Class ConsThread

class ConsThread extends Thread { ProdCons parent; ConsThread(ProdCons parent) { this.parent = parent; } public synchronized void canConsume() { notify(); } public void run() { boolean consumed; do { synchronized(this) { try { wait();} catch (Exception e) { ; } } do { String str = (String)parent.list.remove(); if ( null == str) { consumed = false; break; } consumed = true; System.out.println("Consumer =>consumed " + str); } while ( true ); } while (consumed); } } 表C: Class ProdThread class ProdThread extends Thread { ProdCons parent; ProdThread(ProdCons parent) { this.parent = parent; } public void run() { for ( int i = 0; i < 10; i++) { String str = new String("ImAString" + i); System.out.println("Producer produced " + str); parent.list.add(str); parent.consumer.canConsume(); } parent.consumer.canConsume(); } }

注意:notify和wait两个API都必须位于同步化(synchronized)的方法中或者代码块中!

线程基础(第二部分)Java线程的缺陷和副作用几解决办法

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号