想定义两个线程交替运行,以sum为指标,sum=0 运行线程0,在线程0里把,sum设为1;sum=1时运行线程1,在线程1里,把sum置为0,依次循环,并计算线程交替时间。
结果应该是
0
1
0
1
0
1
0
1
。高手看看我的程序哪里出错:class  Number0   extends   Thread{
           
        //public long lasting;
        public void run()
        {
             if (SumStore.sum == 0)
             {
                  SumStore.sum = 1;
                  System.out.println("thread0 and sum is  " + SumStore.sum);
                  
             }
                  //lasting   =   System.currentTimeMillis();
                  //long cost =
                  //System.out.println("threadswitch time " + cost);
                  //return;
                                //}
        }
             
       
}
class   Number1   extends   Thread{
   
    public long starting,lasting;
    public  void   run()
    {
              
        if (SumStore.sum == 1)
        {
         SumStore.sum = 0;     
            System.out.println("thread1 and sum is  " + SumStore.sum);
        }
                  
       
        
        //starting   =   System.currentTimeMillis();
        //long cost = starting - lasting;
        //System.out.println("threadswitch time " + cost);
    }
}class SumStore {    public static int sum = 0;}
/////////////////////////////////////////////////////////////////////////
public   class   threadswitching
{/**
  *   @param   args
  */
public   static   void   main(String[]   args)   throws   Exception
{
   
    for(int i=1; i<3; i++){
Thread   t1   =   new   Number0();
Thread   t2   =   new   Number1();
t1.start();
t2.start();
    }}
}
    

解决方案 »

  1.   


    class Number0 extends Thread {
    // public long lasting;
    public void run() {
    while (true) {
    synchronized (SumStore.class) {
    try {
    if (SumStore.sum == 0) {
    SumStore.sum = 1;
    System.out.println("thread0 and sum is  "
    + SumStore.sum);
    }
    SumStore.class.notifyAll();
    Thread.sleep(300);
    } catch (Exception e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    }
    }
    // lasting = System.currentTimeMillis();
    // long cost =
    // System.out.println("threadswitch time " + cost);
    // return;
    // }
    }}class Number1 extends Thread {
    public long starting, lasting;
    public void run() {
    while (true) {
    synchronized (SumStore.class) {
    try {
    SumStore.class.wait();
    if (SumStore.sum == 1) {
    SumStore.sum = 0;
    System.out.println("thread1 and sum is  "
    + SumStore.sum);
    }
    Thread.sleep(300);
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    }
    }
    // starting = System.currentTimeMillis();
    // long cost = starting - lasting;
    // System.out.println("threadswitch time " + cost);
    }
    }class SumStore {
    public static int sum = 0;
    }// ///////////////////////////////////////////////////////////////////////
    public class threadswitching {
    /**
     * @param args
     */
    public static void main(String[] args) throws Exception {
    Thread t1 = new Number0();
    Thread t2 = new Number1();
    t1.start();
    t2.start(); }
    }
      

  2.   

    不知道你说的问题是不是:为什么程序的结果是
    1
    0
    1
    0
    而不是







    1
    修改如下:
    class  Number0   extends   Thread{ 
                
            //public long lasting; 
            public void run() 
            { 
                 if (SumStore.sum == 0) 
                 { 
                      System.out.println("thread0 and sum is  " + SumStore.sum);
                    //上面的输出放在SumStore.sum = 1; 之前
                      SumStore.sum = 1; 
                                         
                 } 
                      //lasting   =   System.currentTimeMillis(); 
                      //long cost = 
                      //System.out.println("threadswitch time " + cost); 
                      //return; 
                                    //} 
            } 
                  
            

    class   Number1   extends   Thread{ 
        
        public long starting,lasting; 
        public  void   run() 
        { 
                   
            if (SumStore.sum == 1) 
            { 
            System.out.println("thread1 and sum is  " + SumStore.sum); //把这句放在SumStore.sum = 0;   
             SumStore.sum = 0;      
                } 
                       
            
             
            //starting   =   System.currentTimeMillis(); 
            //long cost = starting - lasting; 
            //System.out.println("threadswitch time " + cost); 
        } 
    } class SumStore {     public static int sum = 0; } 
    ///////////////////////////////////////////////////////////////////////// 
    public   class   threadswitching 
    { /** 
      *   @param   args 
      */ 
    public   static   void   main(String[]   args)   throws   Exception 

        
        for(int i=1; i <3; i++){ 
    Thread   t1   =   new   Number0(); 
    Thread   t2   =   new   Number1(); 
    t1.start(); 
    t2.start(); 
        } } 

                                                
      

  3.   

    ustbsjl 很好的解释了你的问题
      

  4.   

    是啊,1楼的答案应该是对的,楼主的代码里连同步都没有,肯定会出错了。应该温习一下操作系统进程同步的知识
    if (SumStore.sum == 1) 
            { 
             SumStore.sum = 0;      
                System.out.println("thread1 and sum is  " + SumStore.sum); 
            } 
    像这里面,操作一个竞争资源,没同步怎么行呢
      

  5.   

    谢谢大家的回答,我是java新手,操作系统也在学习中:-)请问,怎么样才能计算线程交替所需的时间呢?是在线程0的结束和线程1的开始处分别设置timer,然后相减嘛?
      

  6.   

    不好意思,初来乍到,不知道规矩。把自己的最终源码贴一下:public class ThreadSwitch {    static final boolean DEBUG = true;    /**
         * Data shared between cooperating threads.
         */
        public static class GuardedData extends Object {
    int sum = 0;;
    int counter = 0;
    int initCounter = 0;
    public long [][] times; public GuardedData(int initSum, int initCounter) {
        this.initCounter = initCounter;
        setSum( initSum );
        setCounter( initCounter );
        times = new long[ initCounter ][2];
    } public int getInitCounter() {
        return initCounter;
    } public int getCounter() {
        return counter;
    }
    public void setCounter(int theCount) {
        counter = theCount;
    } public int getSum() {
        return sum;
    }
    public void setSum( int sum ) {
        this.sum = sum;
    }
        } //end class GuardedData
        /**
         * Sub-class of Thread to toggle between sum (flag) of 0 and 1. 
         */
        public static class Toggler extends Thread {
    /** only start working when sum is this value */
    int targetNum = 0;
    /** sum is set to this value when one iteration is done */
    int waitForNum = 1;
    /** keeps track of the sum, counter */
    GuardedData sharedData = null; public Toggler(String name, int waitForNum, int targetNum, GuardedData sharedData) {
        super(name);     
        this.sharedData = sharedData;
        this.waitForNum = waitForNum;
        this.targetNum = targetNum;
    } public void run() {
        while( true ) {
    //use the GuardedData as lock / monitor
    synchronized( sharedData ) {
        if( sharedData.getCounter() <= 0)
    return;
        while( sharedData.getSum() != waitForNum ) {
    try {
        sharedData.wait();
    } catch( InterruptedException ex ) {}
        }
        if( sharedData.getCounter() <= 0)
    return;     int sum = sharedData.getSum();
        int counter = sharedData.getCounter();
        int initCounter = sharedData.getInitCounter();
        
        //save start time
        long ts = System.currentTimeMillis();
        sharedData.times[ initCounter - counter ][ 0 ] = ts;
        if( DEBUG )
    System.out.println("start " + ts);     if( DEBUG ) //without debug output (end - start) is most likey < 1 ms
    System.out.println( "\t" + getName() + " working on sum = " + sum 
        + ", counter = " + counter );
        //add to the processing time of each thread;
        //(end - start) may be zero since there's no real work taking 1 ms or more.
        try {
    Thread.sleep( 100 );
        } catch( InterruptedException ex ) {}     //update sum, counter
        sharedData.setSum( targetNum );
        sharedData.setCounter( counter - 1  );     //save end time
        ts = System.currentTimeMillis();
        sharedData.times[ initCounter - counter ][ 1 ] = ts;
        if( DEBUG ) {
    System.out.println("end " + ts);
    System.out.println( "--------------------------------------" );
        }          //wake up other threads waiting on sum to become targetNum
        sharedData.notifyAll();
    }
        }
    }//end run
        } //end clas Toggler    
        public static void main(String [] args) {

    GuardedData sharedData = new GuardedData( 0, 20 );
    Toggler thread0 = new Toggler( "Thread 0", 1, 0, sharedData);
    Toggler thread1 = new Toggler( "Thread 1", 0, 1, sharedData); thread0.start();
    thread1.start(); try {
        thread0.join();
        thread1.join();
    } catch (InterruptedException ex) {
    }
    if( ThreadSwitch.DEBUG ) {
        System.out.println( "done" );
        System.out.println();
    }

    System.out.println("start time, end time");
    printArray( sharedData.times );    }//end main    static void printArray(long [][] theArray ) {
    int i, j;
    for(j = 0; j < theArray.length; j++ ) {
        System.out.print( "[ " );
        for(i = 0; i < theArray[j].length - 1; i++) {
    System.out.print( theArray[j][i] + ", ");
        }
        System.out.println( theArray[j][i] + " ]");
    }
        }
    }//end class