初学编程,编了一个小东西,结果和预期不相符!???用Math类中的随机函数产生10000个随机数并存于数组。
              从键盘接收一个数x,然后用多线程并发查找x在数组中的所有下标位置。
              查找线程的构造函数形参如下所示:
               数组名,  查找范围(起始下标、结束下标)
               每个线程体在查找范围内顺序查找,并将该范围内所有找到的x的下标记录到共享的一个内存缓冲区。
               创建上述线程类的四个实体对象,用四个线程将数组分成不重叠的4段进行查找,如果查找失败,则内存缓冲区为空,输出相应信息;否则顺序输出缓冲区中的所有下标位置(注意:这些下标位置并不是由小到大顺序排列的)。??import java.util.*;
import java.io.*;
public class Lookthread 
{  public  static void main(String args[])
    {  Look look1,look2,look3,look4;
  Result re=new Result();
  int rd[];
     rd=new int[10000];
     for(int i=0;i<10000;i++)rd[i]=(int)(Math.random()*10000)+1;
  look1=new Look(rd,0,2499,10,re); 
  look2=new Look(rd,2500,4999,10,re); 
  look3=new Look(rd,5000,7499,10,re); 
  look4=new Look(rd,7500,9999,10,re); 
  look1.start();  
  look2.start(); 
  look3.start(); 
  look4.start(); 
  System.out.println(Result.a);  
  Result.output();   
    }
}
class Result
{public static int result[];
public static int a;
public Result(int n)
  {
   a=0;
   result=new int[n];
  }
public Result()
  {
   a=0;
   result=new int[100];
  }
public void insert(int b)
  {
   result[a]=b;
   a++;
  }
public static void output()
  {
   int j;
   if(a==0){System.out.println("没有这个数字");}
   else if(a!=0){
    for(j=0;j<a;j++)System.out.print(result[j]+" ");
    System.out.println("\n");
    }
  }
}
class Look extends Thread
{    
    Result result;
  int x,start,end,rd[];
    Look(int rd[],int start,int end,int x,Result result) 
    {
  this.rd=rd;
  this.start=start;
  this.end=end;
      this.x=x;
      this.result=result;
    }
    public void run()
    {  //测试行1
  //System.out.println(start+"--"+end);
     for(int i=start,j=end;i<=j;i++)
        {  if(rd[i]==x)result.insert(i);
        }
  //测试行2、3
  //System.out.println(Result.a);  
  //Result.output(); 
    } 
}

解决方案 »

  1.   

    你的预期是什么?没看懂。
    不过Result的insert方法被多个线程调用,是不是应该加一个synchronized?
      

  2.   

    [Quote=引用 5 楼 hwaipy 的回复:]
    你的预期是什么?没看懂。
    不过Result的insert方法被多个线程调用,是不是应该加一个synchronized?
    [/Quote
    我加个 synchronized试试!
      

  3.   

    哦 我知道了  你在把4个Look start以后 马上就输出了结果 这是不对的 因为Thread,start是启动了一个新的线程,而你目前的这个线程仍然会继续执行 
    所以你在打印结果的时候 4个Look甚至都还没有执行完 当然和预期不符解决方案:使用闭锁CountDownLatch。
    初始化:CountDownLatch cdl = new CountDownLatch(4);
    这样一个闭锁,初始时处于关闭状态,当调用它的countDown方法4次以后,就处于打开状态。
    使用方法:在main中初始化一个CountDownLatch,通过Look 的构造方法传入Look对象。然后在start了所有4个Look以后,调用CountDownLatch的await方法。由于这时候CountDownLatch处于关闭状态,主线程执行到这里的时候会“阻塞”。另外,在每个Look的run中最后执行一个CountDownLatch的countDown方法。这样当4个Look都执行完了以后,CountDownLatch就会开启,主线程又可以继续,最终打印结果。
    当然,Result的insert方法被多个线程调用,要加一个synchronized。代码修改如下:
    import java.util.concurrent.CountDownLatch;public class Lookthread {    public static void main(String args[]) throws InterruptedException {
            Look look1, look2, look3, look4;
            Result re = new Result();
            CountDownLatch cdl = new CountDownLatch(4);
            int rd[] = new int[10000];
            for (int i = 0; i < 10000; i++) {
                rd[i] = (int) (Math.random() * 100) + 1;
            }
            look1 = new Look(rd, 0, 2499, 10, re, cdl);
            look2 = new Look(rd, 2500, 4999, 10, re, cdl);
            look3 = new Look(rd, 5000, 7499, 10, re, cdl);
            look4 = new Look(rd, 7500, 9999, 10, re, cdl);
            look1.start();
            look2.start();
            look3.start();
            look4.start();
            cdl.await();
            System.out.println(Result.a);
            Result.output();
        }
    }class Result {    public static int result[];
        public static int a;    public Result(int n) {
            a = 0;
            result = new int[n];
        }    public Result() {
            a = 0;
            result = new int[100];
        }    public synchronized void insert(int b) {
            result[a] = b;
            a++;
        }    public static void output() {
            int j;
            if (a == 0) {
                System.out.println("没有这个数字");
            } else if (a != 0) {
                for (j = 0; j < a; j++) {
                    System.out.print(result[j] + " ");
                }
                System.out.println("\n");
            }
        }
    }class Look extends Thread {    Result result;
        int x, start, end, rd[];
        private final CountDownLatch cdl;    Look(int rd[], int start, int end, int x, Result result, CountDownLatch cdl) {
            this.rd = rd;
            this.start = start;
            this.end = end;
            this.x = x;
            this.result = result;
            this.cdl = cdl;
        }    public void run() { //测试行1
            //System.out.println(start+"--"+end);
            for (int i = start, j = end; i <= j; i++) {
                if (rd[i] == x) {
                    result.insert(i);
                }
            }
            //测试行2、3
            //System.out.println(Result.a);
            //Result.output();
            cdl.countDown();
        }
    }