background image

 ReturnThreadInfo returnThreadInfo = new ReturnThreadInfo();
 returnThreadInfo.start();//创建并启动 ReturnThreadInfo 线程
 
  System.out.println(returnThreadInfo.getThreadInfo());// 获 取 并 输 出
returnThreadInfo 对象的 str 的值
 
 }
 }
 
 以上是一个多数熟悉单线程编程的人在第一反应下给出的实现方法。但是该类在运行的
时候输出的结果却不是期望的"Hello World!"而是"Hello",这是由于线程的竞争条件导
致的(由于 ReturnThreadInfo 线程和 Main 线程的优先级都为 5,所以在很大几率上
ReturnThreadInfo 线 程 的 run() 方 法 还 没 有 运 行 , Main 类 就 已 经 运 行
System.out.println(returnThreadInfo.getThreadInfo());将"Hello"输出了。具体的原
理 可 以 参 见 另 一 篇 文 章 : "java 多 线 程 的 几 点 误 区 ") 。 有 的 人 可 能 会 立 即 想 到 把
ReturnThreadInfo 线程的优先级设高些(比如最大的 10)就可以 returnThreadInfo 线程

run()

Main

System.out.println(returnThreadInfo.getThreadInfo())再运行,这样输出的结就一
定是期望的"Hello World!"了。这种通过调整线程优先级的方法固然可以在某种程度上解
决该问题,但是线程争用 CPU 运行时间的原理却决不仅仅只是优先级高低的原因(优先
级高的线程并不意味着一定比优先级低的线程先运行,只是几率要更大一些)。你并不希
望 ReturnThreadInfo 线程 9999 次都比 Main 先运行,却在最关键的一次在 Main 之后
再运行。因此下面给出两种比较常见的获取线程信息的方法:
 一、轮询
 比较常见的一种解决方案是,让线程类获取方法在结果字段设置之前返回一个标志值。
然后主线程定时询问获取方法,看是否返回了标志之外的值。以下给出了具体的实现方法,
该方法不断测试 str 的值是否为"Hello",如果不为"Hello"才打印输出它。例如:
 package threadtest1;
 /**
 *
 * @author shi mingxiang
 */
 public class Main{
 public Main() {
 }
 /**
 * @param args the command line arguments
 */
 public static void main(String[] args) {
 ReturnThreadInfo returnThreadInfo = new ReturnThreadInfo();
 returnThreadInfo.start();//创建并启动 ReturnThreadInfo 线程
 
 while(true){
 String str = returnThreadInfo.getThreadInfo();