我刚开始学习线程背后的概念而且我遇到了问题。
我有一个N Strings
数组,其中N
是可变的,但总是<= 5
。
我有另一个容量为N
的空数组。
现在,我必须对每个字符串one by one
进行一些复杂的计算,每个结果都在空数组中,与刚检查的字符串在同一索引上。
当一切都结束时,将分析结果数组并保留最长的结果。所有这一切发生的线程都是主线程。
计算花了很多时间,所以我在想是否值得打开N
新主题,并一起评估所有这些。
值得一提的是,计算涉及在HashMap<String, customObject>
上查找字符串,这与所有字符串相同。因此,对于线程,他们将一起访问它。他们不会编辑它,只是寻找值。地图可以更改,但在执行时永远不会更改,因为它会在代码的后面的主线程中从其他部分更改。
示例:
//Current approach
HashMap<String, Object> m = new HashMap<>(); //filled with 10^6 values
String[] data = new String[3];
Object[] results = new String[3];
results[0] = complexCalculationsAndSearcOnHashMap(data[0]);
results[1] = similarComplexCalculationsAndSearcOnHashMap(data[1]);
results[2] = otherComplexCalculationsAndSearcOnHashMap(data[2]);
//Now every complex calculation has to wait until the last one ended before starting. But the only thing that actually should have to wait is this next line:
Object finalResult = longest(results);
所以我的问题是,我应该构建3个线程并将复杂的计算放在run方法中吗?方便,还是让整个线程概念错了?这在应用程序中造成了瓶颈,需要很长时间才能完成。
线程示例:
HashMap<String, Object> m = new HashMap<>(); //filled with 10^6 values
String[] data = new String[3];
Object[] results = new String[3];
Thread t0 = new Thread(){
public void run(){
results[0] = complexCalculationsAndSearcOnHashMap(data[0]);
}
};
//Thread t1, t2..
//t0.start(), t1.start()...
Object finalResult = longest(results);
如果上一个答案是肯定的,那么如何让最后一行等待所有3个线程完成,而他们独立于另一个运行? 我是否通过循环加入所有3个?
最后但并非最不重要的是,安全以这种方式使用HashMap吗? 或者我应该切换到另一个与线程更好的集合对象? 我已经阅读了几个关于此的想法,似乎没有人同意。 它会慢吗? 我不能失去任何优化,除非此时非常必要。
修改
应该指出,“他们需要很长时间才能完成”不应该被视为理所当然。虽然有97%的时间N功能确实需要很长时间才能完成,但它们几乎可以瞬间发生。 我不知道这是否有所作为。
**编辑2:**
我不仅要问如何运行所有4并等待它们完成,我还需要知道在这种情况下是否正确的做法,或者它是否会改变一件事,我还需要了解如果可以这样使用hashMap。
**有关守则的详情**
答案 0 :(得分:3)
您可以使用简单的方法为每个“计算”创建一个线程
Thread[] workers = new Thread[count];
for (int i = 0; i < count; i++) {
final int index = i;
//create thread to calculate i-th value
workers[i] = new Thread(new Runnable() {
@Override
public void run() {
results[index] = complexCalculationsAndSearcOnHashMap(data[index]);
}
});
workers[i].start();
}
for (int i = 0; i < count; i++) {
//wait until threads execution is finished
workers[i].join();
}
//Test output
System.out.println(Arrays.toString(results));
如果您的计算函数依赖于索引...您可以使用索引选择相应的函数或创建外部循环的线程。