2011-08-26 143 views
0

我已经在这个和其他论坛中检查了不同的问题,但是我没有找到解决我的问题的方法。Java多线程问题.join()

我有一个运行ffmpegexiftool进程的应用程序。我有并发问题,我想用Thread来控制它们。这是我如何建立它:

ExiftoolThread

public class ExiftoolThread extends Thread{ 

    String file; 

    public ExiftoolThread(String file){ 
     this.file = file; 
    } 
    public void run(){ 
       serviceToExiftool(file);//Create metadata file 
    } 
} 

FfmpegThread

public class FfmpegThread extends Thread{ 

    String itemName; 

    public FfmpegThread(String itemName){ 
     this.itemName = itemName; 
    } 
    public void run(){ 
     serviceFFmpeg(itemName);//Create thumbnai froma video 
    } 
} 

主要呼叫

Thread exiftoolThread = new ExiftoolThread(file.getName()); 
     exiftoolThread.run(); 
     try { 
      exiftoolThread.join(3000); 
     } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     log.write("JSON file created.It contains the metadata. "); 


      Thread ffmpegThread = new FfmpegThread(itemName); 
      ffmpegThread.run(); 
      try { 
       ffmpegThread.join(3000); 
      } catch (InterruptedException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
      log.write("Thumbnail created successfully. "); 

此调用完成后,有更多的诉权ns与这些过程的结果一起工作,并且总是有一个错过了。我想这是因为其中一个(exiftool或ffmpeg)会在更早之前完成,然后该过程会在另一个完成之前继续。

我使用ffmpegThread.join(3000);来跳过这个问题,因为documentation说,这个方法一直等到线程死亡。我错过了什么?

在此先感谢

+0

对于'start()'而不是'run()'来说,答案是正确的,但是启动线程只是立即加入它似乎是毫无意义的。你真的想要达到什么目标? –

+0

线程启动,使方法run()中的函数创建一个文件(使用ffmpeg或exiftool),然后当这些动作完成时,我想继续正常的操作。正如下面的建议,我在末尾写了join() –

+0

但是,如果您仅仅在原始线程中执行相同的操作,您会得到什么?如果你保持原始线程在整个时间内被阻塞,那么子线程就会执行任何操作,你可能也会使用原来的线程。 –

回答

1

您必须致电start()才能在新线程中运行代码。另外,join()会阻止当前线程,因此您必须在启动所有线程后调用它。

3

你需要调用Thread.start()而不是Thread.run()你的两个线程。 start()方法实际上是旋转一个新的线程来同时执行代码,而run()方法是一个在调用线程中执行的常规方法。

此外,您可以通过使用java.util.concurrent.CountDownLatch替换join()调用来改善线程同步设置。你的主要代码如下所示:

CountDownLatch latch = new CountDownLatch(2); 
Thread ffmpegThread = new FfmpegThread(itemName, latch); 
Thread exifToolThread = new ExifToolThread(itemName, latch); 
ffmpegThread.start(); 
exifToolThread.start(); 

latch.await(); // With optional timeout 

你的两个辅助线程必须都调用latch.countDown()他们完成时。