请注意,多线程不一定会提高速度。多线程主要用于通过防止不必要的睡眠等来减少空闲 CPU 周期。
对于您提供的内容,我无能为力,但是,我认为您可以从以下操作开始:
- 使用线程安全的数据结构。这是必须的。如果你错过了这个
一步,你的软件最终会崩溃。你会有一个
很难查明原因。 (例如,如果你有一个 ArrayList,
使用线程安全的)
- 您可以通过删除 for 循环开始尝试多线程
而是为每次执行使用一个线程。如果你的 for 循环
大小超过线程的数量,你将拥有
将它们排入队列。
- 您的最终计算需要所有其他线程
结束。您可以使用 CountDownLatch、wait()/notifyAll() 或
synchronized() 取决于您的实现。
- 执行最终计算。
编辑
响应(2):
你当前的执行是这样的:
for (int i = 0; i < mylist.size(); i++) {
some_processes();
}
// then start calculation on all hashmaps
calculate_all();
现在,要删除“for”循环,您可以首先从增加“for”循环开始。例如:
// Assuming mylist.size() is around 500 and you want, say 5, hardcoded multi-thrads
Thread_1:
for (int i = 0; i < 100; i++) {
some_processes();
}
Thread_2:
for (int i = 100; i < 200; i++) {
some_processes();
}
Thread_3:
for (int i = 200; i < 300; i++) {
some_processes();
}
Thread_4:
for (int i = 300; i < 400; i++) {
some_processes();
}
Thread_5:
for (int i = 400; i < mylist.size(); i++) {
some_processes();
}
// Now you can use these threads as such:
CountDownLatch latch = new CountDownLatch(5);
ExecutorService executor = Executors.newFixedThreadPool(5);
executor.submit(new Thread1(latch));
executor.submit(new Thread2(latch));
executor.submit(new Thread3(latch));
executor.submit(new Thread4(latch));
executor.submit(new Thread5(latch));
try {
latch.await(); // wait until latch counted down to 0
} catch (InterruptedException e) {
e.printStackTrace();
}
// then start calculation on all hashmaps
calculate_all();
如您所见,这种方法有几个缺点。例如,如果列表大小变为 380 怎么办?然后你有一个空闲线程。另外,如果你想要超过 5 个线程怎么办?
所以此时,您可以通过使“for”循环越来越少来进一步增加“for”循环的数量。最多,“for loop count”==“thread count”,有效地删除你的for循环。所以从技术上讲,你需要“mylist.size()”数量的线程。您可以这样实现:
// Allow a maximum amount of threads, say mylist.size(). I used LinkedBlockingDeque here because you might choose something lower than mylist.size().
BlockingQueue<String> blockingQueue = new LinkedBlockingDeque<>(mylist.size());
CountDownLatch latch = new CountDownLatch(mylist.size());
new Thread(new add_some_processes_w_single_loop_for_loop_to_queue(queue, latch)).start();
new Thread(new take_finished_processes_from_queue(queue)).start();
try {
latch.await(); // wait until latch counted down to 0
} catch (InterruptedException e) {
e.printStackTrace();
}
// then start calculation on all hashmaps
calculate_all();
请注意,通过这种安排,我们已经删除了您最初的“for”循环,而是创建了另一个仅在队列清空时提交新线程的循环。您可以使用生产者和消费者应用程序检查 BlockingQueue 示例。例如参见:BlockingQueue examples
编辑 2
Future 的简单实现可能如下所示:
ExecutorService executorService = Executors.newCachedThreadPool();
Future future1, future2, future3, future4, future5, future6;
for (int i = 0; i < mylist.size(); i++) {
long startepoch = getTime(mylist.get(i).time);
MyItem m = mylist.get(i);
String index=(i+1)+"";
future1 = executorService.submit(new Callable() {...})
//adds to hashmap1
future1.get(); // Add this if you need to wait for process1 to finish before moving on to others. Also, add a try{}catch{} block as shown below.
if(m.name.equals("TEST")) {
future2 = executorService.submit(new Callable() {...})
//adds to hashmap2
future2.get(); // Add this if you need to wait for process2 to finish before moving on to others. Also, add a try{}catch{} block as shown below.
} else {
future3 = executorService.submit(new Callable() {...})
//adds to hashmap3
future4 = executorService.submit(new Callable() {...})
//adds to hashmap4
future5 = executorService.submit(new Callable() {...})
//adds to hashmap5
future6 = executorService.submit(new Callable() {...})
//adds to hashmap6
// Add extra future.get here as above...
}
}
// then start calculation on all hashmaps
calculate_all();
不要忘记添加 try-catch 块,否则您可能无法从异常和崩溃中恢复。
// Example try-catch block surrounding a Future.get().
try {
Object result = future.get();
} catch (ExecutionException e) {
//Do something
} catch (InterruptedException e) {
//Do something
}
但是,您可以有一个更复杂的,如here 所示。该链接也解释了 Thilo 的回答。