简体   繁体   English

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

[英]How can multithreading help increase performance in this situation?

I have a piece of code like this: 我有一段这样的代码:

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;
}

What I know is using multithreading can save time when one thread is get blocked by I/O or network. 我所知道的是,当一个线程被I / O或网络阻塞时,使用多线程可以节省时间。 In this synchronous operations every step have to wait for its previous step get finished. 在此同步操作中,每一步都必须等待其上一步完成。 What I want here is to maximize cpu utilization on getTokens() . 我在这里想要的是最大化getTokens()上的cpu利用率。

My first thought is put getTokens() in the run method of a class, and create multiple threads. 我的第一个想法是将getTokens()放在类的run方法中,并创建多个线程。 But I think it will not work since it seems not able to get performance benefit by having multiple threads on pure computation operations. 但是我认为这是行不通的,因为通过在纯计算操作上使用多个线程似乎无法获得性能优势。

Is adoption of multithreading going to help increase performance in this case? 在这种情况下,采用多线程是否有助于提高性能? If so, how can I do that? 如果是这样,我该怎么做?

It will depend on the pace that jdbc_readOperation() produces data to be processed in comparison with the pace that getTokens(x) processes the data. 与getTokens(x)处理数据的速度相比,这取决于jdbc_readOperation()产生要处理的数据的速度。 Knowing that will help you figure out if multi-threading is going to help you. 知道这一点将帮助您确定多线程是否对您有所帮助。

You could try something like this (just for you to get the idea): 您可以尝试这样的操作(仅是为了您理解):

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();

Or you could learn how to use the ThreadPoolExecutor. 或者,您可以学习如何使用ThreadPoolExecutor。 ( https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ThreadPoolExecutor.html ) https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ThreadPoolExecutor.html

Okay to speed up getTokens() you can split the inputted String divText by using String.substring() method. 可以加快getTokens()的速度,可以使用String.substring()方法拆分输入的String divText。 You split it into as many substrings as you will run Threads running the getTokens() method. 您将其拆分为与运行getTokens()方法的线程一样多的子字符串。 Then every Thread will "run" on a certain substring of divText. 然后,每个线程将在divText的某个子字符串上“运行”。

Creating more Threads than the CPU can handle should be avoided since context switches create inefficiency. 由于上下文切换会导致效率低下,因此应避免创建超出CPU处理能力的线程。

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

An alternative could be splitting the inputted String of getTokens with the String.split method http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#split%28java.lang.String%29 eg in case the text is made up of words seperated by spaces or other symbols. 一种替代方法是使用String.split方法http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#split%28java.lang.String%拆分输入的getTokens字符串。 29例如,在文本由用空格或其他符号分隔的单词组成的情况下。 Then specific parts of the resulting String array could be passed to different Threads. 然后,可以将所得String数组的特定部分传递给不同的Threads。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM