我有这样的代码:
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,例如如果文本由空间或其他符号分开的单词组成。然后,可以将结果字符串数组的特定部分传递到不同的线程。