在这种情况下,多线程如何帮助提高性能?

时间:2016-12-06 01:02:34

标签: java multithreading thread-safety threadpool

我有一段这样的代码:

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方法中,并创建多个线程。但我认为它不会起作用,因为它似乎无法通过在纯计算操作上使用多个线程来获得性能优势。

在这种情况下采用多线程是否有助于提高性能?如果是这样,我该怎么做?

2 个答案:

答案 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。