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



我有这样的代码:

while(){
    x = jdbc_readOperation();
    y = getTokens(x);
    jdbc_insertOperation(y);
}
public List<String> getTokens(String divText){
    List<String> tokenList = new ArrayList<String>();
    Matcher subMatcher = Pattern.compile("\[[^\]]*]").matcher(divText);
    while (subMatcher.find()) {
        String token = subMatcher.group();
        tokenList.add(token);
    }
    return tokenList;
}

我所知道的是使用多线程可以节省时间,当一个线程被I/O或网络阻止时。在此同步操作中,每个步骤都必须等待其上一步完成。我想要的是在 getTokens()上最大化CPU利用率。

我的第一个想法是将GetTokens()放在类的运行方法中,并创建多个线程。但是我认为这将行不通,因为在纯计算操作上拥有多个线程似乎无法获得性能益处。

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

这将取决于jdbc_readoperation()与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/java/util/concurrent/threadpoolexecutor.html)

可以加速getTokens()您可以使用string.substring()方法将输入的字符串DivText拆分。您将其分为多数子字符串,因为您将运行运行getTokens()方法的线程。然后,每个线程都会在DivText的某个子字符串上"运行"。

由于上下文开关造成效率低下,因此应避免使用比CPU可以处理更多的线程。

https://docs.oracle.com/javase/8/docs/api/java/java/lang/string.html#substring-int-int-int-int-

可以使用string.split method http://docs.oracle.com/javase/7/docs/api/java/java/java/lang/lang/string.html#split(java.lang

可以用String.split metag.String%29,例如如果文本由空间或其他符号分开的单词组成。然后,可以将结果字符串数组的特定部分传递到不同的线程。

最新更新