犹豫再三,还是决定提问,这两天线程的执行顺序搞的我好晕!!
class Q { 
  int n; 
  boolean valueSet=true;
 
  synchronized void put(int n) { 
    if(!valueSet)
      try{
        wait();
      }catch(InterruptedException e){
        System.out.println("Interrupted exception caught.");
      }
      this.n = n; 
      System.out.println("Put: " + n); 
      valueSet=false;
      notify();
  }   synchronized int get() { 
    if(valueSet)
      try{
        wait();
      }catch(InterruptedException e){
        System.out.println("Interrupted exception caught.");
      }
      System.out.println("Got: " + n); 
      valueSet=true;
      notify();
      return n; 
  } 

//======================================================
class Producer implements Runnable { 
  Q q; 
 
  Producer(Q q) { 
    this.q = q; 
    new Thread(this, "Producer").start(); 
  } 
 
  public void run() { 
    int i = 0;  
//  while(true) { 
    for(int m=15;m>0;m--)
    q.put(i++); 
//  } 
  } 

//====================================================== 
class Consumer implements Runnable { 
  Q q; 
 
  Consumer(Q q) { 
    this.q = q; 
    new Thread(this, "Consumer").start(); 
  } 
 
  public void run() { 
//  while(true) { 
    for(int m=15;m>0;m--)
    q.get(); 
//  } 
  } 

//====================================================== 
class PC { 
  public static void main(String args[]) { 
    Q q = new Q(); 
    new Producer(q); 
    new Consumer(q);  
    System.out.println("Press Control-C to stop."); 
  } 

//====================================================== 
在单位电脑的赛洋单核CPU上执行结果:
Press Control-C to stop.
Put: 0
Got: 0
Put: 1
Got: 1
... ...
在家里的AMD双核4000+上的执行结果:
Put: 0
Press Control-C to stop.
Got: 0
Put: 1
Got: 1
... ...
其实这个main的println语句什么时候执行我还是不明白。
println在main方法的最后,据我的理解应该在所有子线程结束之后执行,或在子线程互斥的间隙执行。
main的println为什么会最先执行呢?
子线程的互斥应该没有间隙啊,为什么main的println出线在Put: 0与Got: 0中间呢? 
难道主线程和所有子线程的执行顺序都是随机的?

解决方案 »

  1.   

    我来说:线程在cpu的调用顺序是根据一定的算法定义的,叫cpu调度算法,百度能查到。为什么main的println最先调用,因为其他线程start时是进入就绪状态,还没进入运行状态嘛,或者说main函数的线程还没挂起,你知道了么?把调度算法弄懂了就明白了,这就是为什么thread1.start();thraed2.start();时为什么有时会先运行thread2然后再运行thread1,这些都和调度算法有关系。你明白了么?
      

  2.   

    start并不产生阻塞。
    而start的线程需要做一系列的动作,所以main中靠近start的代码通常比Thread中的代码先执行。
      

  3.   

    关于cpu调度算法以后再说吧,现在要严格控制输出顺序是不是要通过设置线程优先级来完成
      

  4.   

    我要是楼主的话就会自己写代码看看一下,其实优先权,线程的长短都是调度算法的重要知识点。如四楼所说的,除了加优先级以外,你还可以在main函数的println前面加个Thread。sleep(100)之类的句子,保证你能按顺序输出