Java多线程:为什么执行不会在join()停止?

时间:2016-02-03 18:23:37

标签: java multithreading

我有一个模块,可以在开始时从文件中反序列化一堆资源。每个都花费时间,所以我想以多线程方式实现它,以便每个线程摄取一个资源。根据我在网上找到的一些例子,我编写了这个测试类,它代表了我主模块的资源摄取步骤。

public class MultiThreadedResourceIngest {

    private static ResourceClass1 r1 = null;
    private static ResourceClass2 r2 = null;
    private static ResourceClass3 r3 = null;

    static class ResourceReader extends Thread {
        private Thread t = null;
        private int id = -1;
        private String path2read = null;

        ResourceReader( final int id, final String path2read){
           this.id = id;
           this.path2read = path2read;
        }

        public void run() {

           if (path2read != null && path2read.length() > 0)
           {
              switch (id) {
                 case 0:
                    r1 = new ResourceClass1(path2read);
                    break;
                 case 1:
                    r2 = new ResourceClass2(path2read);
                    break;
                 case 2:
                    r3 = new ResourceClass3(path2read);
                    break;
                 default:
                    break;
              }

           }
           log.info(String.format("Thread with id=%d and path=%s exiting", id, path2read));
        }

        public void start ()
        {
           if (t == null)
           {
              t = new Thread (this);
              t.start ();
           }
        }

    }

    public static void main(String[] args) {

        final String[] paths = new String[] {"path1", "path2", "path3"};

        log.info("STARTING MTHREADED READ");
        ArrayList<ResourceReader> rrs = new ArrayList<ResourceReader>();
        for (int i=0; i < paths.length; i++)
        {
           ResourceReader rr = new ResourceReader(i,paths[i]);
           rr.start();
           rrs.add(rr);
        }

        log.info("JOINING");
        for (ResourceReader rr: rrs)
        {
           try {
              rr.join();
           } catch (InterruptedException e) {
              // Thread interrupted
              e.printStackTrace();
           }
        }

        // Want to reach this point only when all resources are ingested
        //
        log.info("MTHREADED FINISHED");
    }

}

所以这里我有3个资源,我想在所有线程完成后才到达标记为// Want to reach this point...的点。这就是为什么我已经实现了join()循环,除非它没有按预期工作,即日志看起来像这样:

STARTING MTHREADED READ
Thread with id=0 and path=path1 exiting
JOINING
Thread with id=2 and path=path3 exiting
MTHREADED FINISHED
Thread with id=1 and path=path2 exiting

在继续操作之前,我需要更改以等待所有资源被读取?

3 个答案:

答案 0 :(得分:2)

您宣布资源阅读器扩展线程 ,但您创建另一个并在start中启动它:

          t = new Thread (this);
          t.start ();

您应该加入此主题,而不是

          rr.join();

因此,只需删除 ResourceReader 中的 start()方法,一切都会正常工作。

答案 1 :(得分:0)

你覆盖了线程的start方法,它不会调用super.start()。 所有这一切start()都会创建一个新的第二个线程。删除第二个线程,不要覆盖start()。

这样,对rr.start()的调用将真正启动rr线程,它将结束,join()也将结束。

答案 2 :(得分:0)

太复杂了!为什么不这样做?

static class ResourceReader implements Runnable {
    ...
    public void run() {
       ...
    }
}

public static void main(String[] args) {
    ...
    ArrayList<Thread> rrs = new ArrayList<>();
    for (int i=0; i < paths.length; i++)
    {
       Thread rr = new Thread(new ResourceReader(i,paths[i]));
       rr.start();
       rrs.add(rr);
    }
    ...
    for (Thread rr: rrs)
    {
       try {
          rr.join();
       } catch (InterruptedException e) {
          ...
       }
    }
    ...
}