菜鸟求教各位大神一个多线程问题?在线等!

swjtu184041 2010-05-20 05:10:24
初学编程,编了一个小东西,结果和预期不相符!

???用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();
}
}
...全文
146 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
Hwaipy 2010-05-21
  • 打赏
  • 举报
回复
哦 我知道了 你在把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();
}
}

swjtu184041 2010-05-21
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 hwaipy 的回复:]
你的预期是什么?没看懂。
不过Result的insert方法被多个线程调用,是不是应该加一个synchronized?
[/Quote
我加个 synchronized试试!
Hwaipy 2010-05-21
  • 打赏
  • 举报
回复
你的预期是什么?没看懂。
不过Result的insert方法被多个线程调用,是不是应该加一个synchronized?
plplum 2010-05-21
  • 打赏
  • 举报
回复
333333333333333333333333
swjtu184041 2010-05-21
  • 打赏
  • 举报
回复
谢谢 懂了! 刚学的 多线程编程!
swjtu184041 2010-05-20
  • 打赏
  • 举报
回复
222222222222222222
plplum 2010-05-20
  • 打赏
  • 举报
回复
2222222222222222222222
swjtu184041 2010-05-20
  • 打赏
  • 举报
回复
111111111111111111111

62,612

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧