august 发表于 2007-11-13 11:19:03

[java]请教下线程的同步块问题


class Print extends Thread{
    int[] array;
    static StringBuffer sb=new StringBuffer();
    static Object ob=new Object();
    public Print(int[] array){
      this.array=array;
    }
    public void addleft(){
      for(int i=0;i<array.length/2;i++){
            sb.append(array);
            try{
                sleep(100);
            }catch(Exception e){
            }
      }
    }
    public void addRight(){
      for(int i=array.length/2;i<array.length;i++){
            sb.append(array);
            try{
                sleep(100);
            }catch(Exception e){
            }
      }
    }
    public void run(){
      
      addleft();
   
      addRight();
      
      
    }
    public static void main(String[] args){
      
      Print a=new Print(new int[]{1,1,1,1,1,2,2,2,2,2});
      Print b=new Print(new int[]{3,3,3,3,3,4,4,4,4,4});
      
      a.start();
      b.start();
      try{
            a.join();
            b.join();
            
      }catch(InterruptedException e){
      }
      System.out.println(sb);
    }
}

请问这里应该怎么修改才可以输出"11111333332222244444" 呢??

rednaxela 发表于 2007-11-13 14:07:32

延续楼主的思路的话,这样:
class Print extends Thread{
    int[] array;
    static StringBuffer sb=new StringBuffer();
    static Object ob=new Object();
    public Print(int[] array){
      this.array=array;
    }
    public void addleft(){
      for(int i=0;i<array.length/2;i++){
            sb.append(array);
      }
      try{
            sleep(100);
      }catch(Exception e){
      }
    }
    public void addRight(){
      for(int i=array.length/2;i<array.length;i++){
            sb.append(array);
      }
      try{
            sleep(100);
      }catch(Exception e){
      }
    }
    public void run(){
      addleft();
      addRight();
    }
    public static void main(String[] args){
      
      Print a=new Print(new int[]{1,1,1,1,1,2,2,2,2,2});
      Print b=new Print(new int[]{3,3,3,3,3,4,4,4,4,4});
      
      a.start();
      b.start();
      try{
            a.join();
            b.join();
            
      }catch(InterruptedException e){
      }
      System.out.println(sb);
    }
}
注意那两段sleep(100)的位置.或者把那两段sleep换成Thread.yield()也可以.

但是需要指明的是,这么做不是"线程安全"的.只使用sleep()或者yield无法保证执行顺序.在这里,虽然先调用了a.start(),但却无法保证a.run()在b.run()之前得到有效执行.虽然很难得一见b在a之前得到执行的状况,但它确实存在.
要保证执行顺序,最直观且有效的办法就是显式同步.不过在楼主给的这个例子里,强行通过同步来达到顺序没什么意义.如果是生产者-消费者/哲学家用餐之类的问题的话,还有点意义可言...

lw 发表于 2007-11-13 19:23:33

通常是WAIT等PV操作比较适用罢,也看具体情况了
页: [1]
查看完整版本: [java]请教下线程的同步块问题