当前位置:编程学习 > JAVA >>

帮忙分析一个线程问题

 public class Computation extends Thread {
  private int num;
  private boolean isComplete;
  private int result;
  public Computation(int num) {
   this.num = num;
  }
  public synchronized void run() {
   result = num * 2;
   isComplete = true;
   notify();
  }
  public synchronized int getResult() {
   while (!isComplete) {
    try {
     wait();
    } catch (InterruptedException e) {
    }
   }
   return result;
  }
  public static void main(String[] args) {
   Computation[] computations = new Computation[4];
   for (int i = 0; i < computations.length; i++) {
    computations[i] = new Computation(i);
    computations[i].start();
   }
   for (Computation c : computations)
    System.out.print(c.getResult() + " ");
  }
 } 
对这个问题,我有以下2个疑惑:
       1.这个程序有必要加synchronized给  getResult()和run()方法吗?建立四个线程,我认为这四个线程是彼此独立的线程,根本不会存在有并发的情况。我试着把synchronized关键字和notify和 wait方法去掉之后,结果输出的结果跟之前的一模一样。
        2.为什么这个题目的输出顺序,一直是0 2 4 6,并且顺序一直不会改变。按理说,四个线程创建后,进入就训状态,被CPU分配时间片也是随机的(我在run()方法里做了测试,是这样的)。那么输出的顺序也该是随机的。到底这程序哪个地方保证了它按顺序输出呢? 多线程 并发 同步 同步 --------------------编程问答-------------------- 首先run方法不需要加锁。
实际中加锁的只是对数据进行修改的方法需要加锁。
另外楼主是new了很多对象来进行线程,这样每个线程都有自己的一个对象。
我猜楼主其实想要的结果是一个对象的四个线程,这才对。
改成

  computations = new Computation(i);
  computations.start();
computations.start();
computations.start();
看效果
  --------------------编程问答-------------------- 感觉上楼主 新建进程全放到一个数组中 不管你线程怎么跑的顺序 你的数组中的序号是肯定的
你又是按照万能遍历数组 来运行这个数组中对象的方法 这个其实和线程已经没有什么关系 
完全可以看成是在操作普通对象。
要看结果 你在run()
中调用getResult结果,而不是去循环调用对像中的方法 这就有点像调用直接调用run()方法一样 没有线程并发的操作的现象。。。。。 --------------------编程问答-------------------- 除 --------------------编程问答-------------------- 这是scjp认证题的一道吧。主要就是在后面的输出数组上面。数组中getResult的顺序都确定了。前面执行完成就输出,没有执行完成就等待。
意思是四个线程的run方法执行顺序无所谓。主要就是最后的那个输出上面。 --------------------编程问答-------------------- 后面输出线程数组是按照顺序的,所以每次输出都是按顺序输出每个对象中的值,当然最后结果是一样的。 --------------------编程问答--------------------
引用 1 楼 AA5279AA 的回复:
首先run方法不需要加锁。
实际中加锁的只是对数据进行修改的方法需要加锁。
另外楼主是new了很多对象来进行线程,这样每个线程都有自己的一个对象。
我猜楼主其实想要的结果是一个对象的四个线程,这才对。
改成

  computations = new Computation(i);
  computations.start();
computations.……


呵呵,谢谢你的耐心解答!
你给程序也确实也保证一个对象四个线程。
   这实际是一道考题,考题就这样的。在实际中,确实也没有对run()方法加过锁。 --------------------编程问答-------------------- 1.加wait跟notify是为了保证最后输出时能得到计算结果。wait和notify必须要加锁。
2.线程运行顺序是不确定的,但输出结果是确定的。就是*2,参数是你循环时确定的。
补充:Java ,  Java SE
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,