我有一段这样的代码:
for (std::set<node>::iterator it = openSet.begin(); it != openSet.end(); it++) {
if ((*it).f < grid[currentNode.y][currentNode.x].f)
currentNode = *it;
}
我知道使用多线程可以节省一个线程被I / O或网络阻塞的时间。在此同步操作中,每个步骤都必须等待其上一步完成。我想要的是在 getTokens()上最大化cpu利用率。
我的第一个想法是将getTokens()放在类的run方法中,并创建多个线程。但我认为它不会起作用,因为它似乎无法通过在纯计算操作上使用多个线程来获得性能优势。
在这种情况下采用多线程是否有助于提高性能?如果是这样,我该怎么做?
答案 0 :(得分:2)
与getTokens(x)处理数据的速度相比,它将取决于jdbc_readOperation()生成要处理的数据的速度。了解这将有助于您了解多线程是否会对您有所帮助。
你可以尝试这样的事情(只是为了让你明白这个想法):
int workToBeDoneQueueSize = 1000;
int workDoneQueueSize = 1000;
BlockingQueue<String> workToBeDone = new LinkedBlockingQueue<>(workToBeDoneQueueSize);
BlockingQueue<String> workDone = new LinkedBlockingQueue<>(workDoneQueueSize);
new Thread(() -> {
try {
while (true) {
workToBeDone.put(jdbc_readOperation());
}
} catch (InterruptedException e) {
e.printStackTrace();
// handle InterruptedException here
}
}).start();
int numOfWorkerThreads = 5; // just an example
for (int i = 0; i < numOfWorkerThreads; i++) {
new Thread(() -> {
try {
while (true) {
workDone.put(getTokens(workToBeDone.take()));
}
} catch (InterruptedException e) {
e.printStackTrace();
// handle InterruptedException here
}
}).start();
}
new Thread(() -> {
// you could improve this by making a batch operation
try {
while (true) {
jdbc_insertOperation(workDone.take());
}
} catch (InterruptedException e) {
e.printStackTrace();
// handle InterruptedException here
}
}).start();
或者您可以学习如何使用ThreadPoolExecutor。 (https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ThreadPoolExecutor.html)
答案 1 :(得分:0)
好的是为了加快getTokens(),您可以使用String.substring()方法拆分输入的String divText。您将它拆分为多个子字符串,因为您将运行运行getTokens()方法的Threads。然后每个线程将“运行”在divText的某个子字符串上。
应该避免创建比CPU可以处理的更多的线程,因为上下文切换会产生低效率。
https://docs.oracle.com/javase/8/docs/api/java/lang/String.html#substring-int-int-
另一种方法是将输入的getTokens字符串与String.split方法http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#split%28java.lang.String%29分开,例如如果文本由空格或其他符号分隔的单词组成。然后,生成的String数组的特定部分可以传递给不同的Threads。