2016-02-03 54 views
1

我有一个模块,可以在启动时从文件中反序列化一堆资源。每个都需要时间,所以我想以多线程的方式实现这一点,以便每个线程获取单个资源。遵循我在网上找到的一些例子,我写了这个测试类,它代表了我主模块的资源吸收步骤。Java多线程:为什么执行不会停在join()?

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 

什么我需要改变等到所有的资源都在继续之前阅读?

回答

2

你宣布ResourceReader延伸主题,但你再创建一个并启动它里面开始:

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

你应该加入这个线程,而不是

  rr.join(); 

所以刚刚删除你的start()方法里面Re sourceReader和一切都会工作。

0

您覆盖了线程的启动方法,它不会调用super.start()。 所有这一开始()所做的是创建一个新的第二个线程。删除第二个线程并且不要覆盖start()。

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

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) { 
      ... 
     } 
    } 
    ... 
} 
相关问题