2011-08-26 154 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()他們完成時。