大家好,我现在做一个项目只能用java 1.4版本,因此没办法用1.5版本中的Callable接口给主线程提供返回值。
      我做的是将各个独立的任务放在多个线程中同时进行,并希望他们在结束后将结果返回到主线程,请问这该怎么做啊,膜拜各路大侠给我指点指点!

解决方案 »

  1.   

    天马行空--- 我的qq的签名也是这个  蛮巧的。主线程中创建一个数据访问安全的对象A,主线程启动的线程thread2初始化时,A作为thread2的初始化参数,thread2在run方法中把操作结果返回给对象A。主线程在thread2未完成操作时等待就好了,直到等待的thread2运行结束 进行下步操作。
      

  2.   

    to QQCrazyBoy
     你自己测试下,是这样的吗?
    线程和线程之间是独立的。
      

  3.   

    主线程里放一个Hashtable ,业务线程把返回结果放进去,主线程里取。
    这样就OK了,另Hashtable是线程安全的,不需要另外加锁
      

  4.   

    楼上的说的方法我还是不太懂,把问题再明确一下:
         每个线程结束都会得到一个List类型的数据,然后主线程需要创建一个更大的List类型的变量,把各个子线程的List数据保存进去,我就是这不太懂怎么实现,咋样创建Hashtable实现呢,况且我的进程数是根据输入任务不同,需要变化的,请再次赐教,在线等!
      

  5.   


    请问一下,Runable接口中的run()函数是不允许有返回值的,如何返回?谢谢!
      

  6.   

    设置一个static静态的变量就可以实现结果共享了。
      

  7.   

    所有子线程都将结果写到公共的缓冲区中(注意并发问题),在启动子线程后,将主线程挂起(wait),直到所有子线程结束后唤醒主线程,此时便可以获取缓冲区中各个子线程写入的内容(相当于子线程饭后的结果)。
      

  8.   

    汗!  楼主我随便写下  大概是这个思路,我写的是伪代码。
    你自己再去改下吧main(){
      Map datas = new Hashedtable();
      MyThreadRun run = new MyThreadRun();
      run.setDatas(datas);
      Thread tt =  new Thread(run);
      tt.start(); 
      
      while(!"result is ok".equal(datas.get("status"))){
         try{
           Thread.sleep(10000);
         }catch(Exception){
           //todo
         }
      }
      //或者使用join 具体的看下api 
      tt.join();   Object result = run.get("result");
       //dosomething
    }static Class MyThreadRun implements Runable{
       Hashedtable datas;
       public void setData(Map data){ 
           this.datas = data;
       }   run(){
          //execute get the result
          this.datas.put("result",result);
          this.datas.put("status","result is ok");
       }
    }
      

  9.   


    main(){
      HashTable datas = new HashTable();
    MainThread  mainThread=new MainThread(datas);
    mainThread.start();//这里的子线程可以多个
      MyThreadRun run = new MyThreadRun();
      run.setDatas(datas);
      Thread tt = new Thread(run);
      tt.start();  
       
    }Class MyThreadRun implements Runable{
      Hashedtable datas;
      public void setData(Map data){  
      this.datas = data;
      }  run(){
      //execute get the result
      this.datas.put("result",result);
      this.datas.put("status","result is ok");
      }
    }class MainThread extends Thread{
    Hashtable table;
       public MainThread(Hashtable table){
         this.table=table;
    }
    public void run(){
       while(true){
    Thread.sleep(1000l);
    List result=table.remove("result");
    if(result!=null){
      //dosomething
    }}}
    }
    参照楼上的代码,随便改下,楼上的大哥不要生气哈。- -!!
      

  10.   

    to wwj85523你该成三个线程了,main方法执行的也有一个线程,不过这么写楼主可能更好理解。不过要改一下,这样写线程不会死了,一般都是使用状态量来控制 while(isAlive)
      if(result!=null){
      //dosomething
      isAlive = false;
    }这样比较好,也可以使用Thread 内置的状态 interrupted
    while(isInterrupted()){
    //dosomethinginterrupted();
    }
      

  11.   


    你这样写是针对只有一个子线程的,如果有多个子线程在同时执行,而且每个子线程结束任务并返回的时间是不同的,但是都返回值的的Hashtable表中的状态标记 "status" = finish.这样对于你的程序就只能返回最开始的一个线程值了。
    还有没有更好的方法呢?谢谢
      

  12.   

    要带返回值的线程。需要JDK1.5以上有Callable 这个
    详细的用法你去看资料。
    给你看看我简单的应用。
    根据返回值判断是否跳出循环的 Callable callable = new ReadInfoTimerTask(unicode, messages);
    Future future = null;
    int i = 1;
    while(messages[2].trim().equals("")) //unicode is empty
    {
    future = SSP.scheduledExecutor.schedule(callable, scanTime, TimeUnit.SECONDS);
    messages = (String[])future.get();
    i++;
    if(i>scanNO)
    // messages[3] = "timeOut";
    break;
    }
    这个是线程public class ReadInfoTimerTask implements Callable {

    private String key;
    private String[] messages; public ReadInfoTimerTask(String unicode, String[] messages){
    this.key = unicode;
    this.messages = messages;
    } public String[] call() throws Exception{
    if(SSP.resultList.get(key)!=null)
    {
    messages = SSP.resultList.get(key);
    SSP.resultList.remove(key);
    }
    return messages;
    }}
    这只是部分的代码,不能直接复制使用,仅供参考
      

  13.   

    说了才看见问题。。不能JDK1.5当我没说。。
      

  14.   

    楼主这个是伪代码,你怎么去判定是不是子线程都执行完毕,完全可以自己设计嘛。例如:引用计数器的方式。main thread 开启几个 son thread,就在计数器中+ji, 
    son thread 运行结束,对计数器-1,当减到0的时候,main thread 判定 son thread 执行完毕,
    开始执行。引用计数器 就是一个线程共享的 线程安全的数据资源。之前的代码也给你了,你可以参照。引用计数器,在 lucene 2.32中 IndexReader 有引用计数器代码,当然有计数器代码的地方应该很多。你可以参照下。
      

  15.   

    public static ConcurrentHashMap<String, List[]> resultList = new ConcurrentHashMap<String, List[]>();      //ConcurrentHashMap支持多线程并发每个线程创建的时候,生成一个UniID保存成key。
    子线程返回的结果,根据这个key保存进resultList。主线程每隔一段时间去遍历这个list
    for(Map.Entry<String, List[]> entry : XXX.resultList.entrySet())
    {
    if(XXX)
    {
    method(entry.getValue(),entry.getKey());
    }
    XXX.resultList.remove(entry.getKey());
    }
    处理完移出list
      

  16.   

    ConcurrentHashMap 不仅仅是支持多线程并发了,它还提供了散列 sagement 的实现方式,分离了 segement 访问的同步锁,从而加速了同步访问速度。
    改进了以往 HashTable 或者 Collections.syn..(Map) 只提供一个 segement 和 单一的同步锁的情况。楼上的朋友很热衷 concurrent 包列。连续的几个建议都是使用这个包。 这个地方没必要使用 ConcurrentHashMap,有点杀鸡用牛刀的感觉,简洁就好,自己设计成线程安全就可以了。
      

  17.   


    package thread;import java.util.ArrayList;
    import java.util.List;public class NoCallable {
    public static void main(String[] args) {
    List<TestThread> list = new ArrayList<TestThread>();
    for (int i = 0; i < 4; i++) {
    TestThread testThread = new TestThread(9999999999L);
    testThread.start();
    list.add(testThread);
    }
    boolean isLoop = true;
    while (isLoop) {
    try {
    Thread.sleep(1000 * 1);
    isLoop = false;
    for (TestThread testThread : list) {
    System.out.println(testThread.isAlive());
    if (testThread.isAlive()) {
    isLoop = true;
    }
    }
    System.out.println();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }

    for (TestThread testThread : list) {
    System.out.println(testThread.getResult());
    }
    }
    }class TestThread extends Thread { private long loopNum;
    private int result = 0; public TestThread(long loopNum) {
    this.loopNum = loopNum;
    } @Override
    public void run() {
    long currentNum = loopNum;
    boolean isOver = false;
    while (!isOver) {
    if (currentNum < 0) {
    isOver = true;
    }
    result++;
    currentNum = currentNum - 2;
    }
    } public long getLoopNum() {
    return loopNum;
    } public void setLoopNum(long loopNum) {
    this.loopNum = loopNum;
    } public int getResult() {
    return result;
    } public void setResult(int result) {
    this.result = result;
    }}
    这个不用Callable 线程这方面俺知识太少了 所以你凑货着看吧。。
      

  18.   

    谢谢大家,我已经搞定了,就如同上面说的那样。给线程类设置一个静态变量,就可以实现线程间的数据共享,然后再创建一个HashTable就可以实现将此线程内的数据传递给主线程。最后对刚起的各个子线程利用Join()方法,使他们全部允许完再回到主线程,就可以完成我的功能,在此谢谢大家。