我在此论坛和其他论坛中检查了不同的问题,但没有找到问题的解决方案。
我有一个运行 ffmpeg
和 exiftool
进程的应用程序。我有并发问题,我想使用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. ");
此调用完成后,还会有更多操作处理这些进程的结果,但总会错过其中一个操作。我想这是因为其中一个(exiftool 或 ffmpeg)较早完成,然后该过程在另一个完成之前继续。
我正在使用ffmpegThread.join(3000);
来跳过这个问题,如documentation说,这个方法会等待直到线程死亡。我缺少什么?
提前致谢
最佳答案
您需要在两个线程上调用 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()
。
关于Java多线程问题.join(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7205486/