我有(比如说)2 个函数,它们执行 db-hit 来获取大量数据。由于这两个函数一个接一个地执行(由同一个线程),所用时间为 T(f(1)) + T(f(2))。如何并行执行这两个函数(通过创建 2 个线程),以便总时间为: T(max(T(f1), T(f2))
我已经完成了完整的 java swing 应用程序的编写,现在想优化它的性能。欣赏任何见解,如果问题太天真,请原谅。
谢谢!
我有(比如说)2 个函数,它们执行 db-hit 来获取大量数据。由于这两个函数一个接一个地执行(由同一个线程),所用时间为 T(f(1)) + T(f(2))。如何并行执行这两个函数(通过创建 2 个线程),以便总时间为: T(max(T(f1), T(f2))
我已经完成了完整的 java swing 应用程序的编写,现在想优化它的性能。欣赏任何见解,如果问题太天真,请原谅。
谢谢!
您还没有说您是否需要函数的任何返回值,但考虑到它们访问数据库的事实,这似乎很有可能。一个非常好的和简单的解决方案是使用 Executors 和 Futures。
完整的代码示例在这里:
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class FuturesExample {
public interface ReturnTypeOne {}
public interface ReturnTypeTwo {}
public void runTwo() {
ExecutorService executor = Executors.newFixedThreadPool(2);
// Dispatch two tasks.
Future<ReturnTypeOne> first = executor.submit(new Callable<ReturnTypeOne>() {
@Override
public ReturnTypeOne call() throws Exception {
// Work, work, work...
return null;
}
});
Future<ReturnTypeTwo> second = executor.submit(new Callable<ReturnTypeTwo>() {
@Override
public ReturnTypeTwo call() throws Exception {
// Work, work, work...
return null;
}
});
// Get the results.
try {
ReturnTypeOne firstValue = first.get();
ReturnTypeTwo secondValue = second.get();
// Combine the results.
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
它由两个部分组成。首先其中两个任务被提交到线程池中。每个 ExecutorService.submit() 调用立即返回任务计算的未来值。任务在 submit() 调用时立即分派,并在后台运行。当然,您可以分派两个以上的任务。
在第二部分中,获得了期货的价值。发生的情况是对 Future.get() 的调用会阻塞当前线程,直到计算出该值。这并不意味着任何任务被阻塞,它们都在运行,线程只是等待给定任务完成并返回一个值。一旦返回第一个值,就会进行第二次 Future.get() 调用。在这种情况下,它可能会或可能不会阻塞。如果第二个任务已经完成(可能在第一个任务之前),则立即返回该值。如果第二个任务仍在运行,则调用会阻塞当前线程,直到计算出该值。
以上归结为您的主线程只会等待最长运行的任务。正是你需要的。
您可以像这样调度 2 个线程:
new Thread(new Runnable()
{
@Override
public void run()
{
// TODO Place your "f(1)" code here...
}
}).start();
new Thread(new Runnable()
{
@Override
public void run()
{
// TODO Place your "f(2)" code here...
}
}).start();