gpt4 book ai didi

java - 使用 java Executor 接口(interface)的多线程方法

转载 作者:行者123 更新时间:2023-12-04 00:33:42 24 4
gpt4 key购买 nike

我正在尝试使用执行程序接口(interface)实现多线程方法,我在主类中生成了多个线程

class Main
{
private static final int NTHREADS = 10;

public static void main(String[] args)
{
.........
String str = createThreads(document);
.............
}


public String createThreads(String docString)
{

........
.......
Map<String,String> iTextRecords = new LinkedHashMap<String, String>();
if(!iText.matches(""))
{
String[] tokenizedItext = iText.split("\\^");
ExecutorService executor = Executors.newFixedThreadPool(NTHREADS);
for(int index = 0 ;index < tokenizedItext.length;index++)
{
Callable<Map<String,String>> worker = null;
Future<Map<String,String>> map = null;
if(tokenizedItext[index].matches("^[0-9.<>+-= ]+$") || tokenizedItext[index].matches("^\\s+$"))
{
iTextRecords.put(tokenizedItext[index],tokenizedItext[index]);
}
else
{
worker = new MultipleDatabaseCallable(tokenizedItext[index],language);
map = executor.submit(worker);
try
{
iTextRecords.putAll(map.get());
}
catch(InterruptedException ex)
{
ex.printStackTrace(System.out);
}
catch(ExecutionException ex)
{
ex.printStackTrace(System.out);
}
}

}

executor.shutdown();
// Wait until all threads are finish
while (!executor.isTerminated())
{

}

}
}

Callable类是

class MultipleDatabaseCallable implements Callable<Map<String,String>> 
{
@Override
public Map<String, String> call() throws Exception {

System.out.println("Entering: "+Thread.currentThread().getName());
Map<String,String> map = new HashMap<String,String>();
for(int i =0;i<50000;i++)
{
for(int i1 = 0 ;i1<5000;i1++)
{
for(int i2 =0;i2 <500;i2++)
{

}
}
}
System.out.println("Exiting: "+Thread.currentThread().getName());
return map;
}
}

我得到的输出是

Entering: pool-1-thread-1
Exiting: pool-1-thread-1
Entering: pool-1-thread-2
Exiting: pool-1-thread-2
Entering: pool-1-thread-3
Exiting: pool-1-thread-3
Entering: pool-1-thread-4
Exiting: pool-1-thread-4
Entering: pool-1-thread-5
Exiting: pool-1-thread-5
Entering: pool-1-thread-6
Exiting: pool-1-thread-6

在查看输出时,似乎一次只有一个线程进入调用方法,而其他线程仅在前一个线程存在时才进入。但是,预计多个线程应该进入并执行 call() 方法。此外,当我通过使 NTHREADS = 1 执行相同的程序时。它花费的时间与 NTHREADS =10 花费的时间相同

所以看起来应用程序运行得和单线程应用程序一样好。请提出我在实现中做错了什么。

谢谢

最佳答案

当你打电话时

                map = executor.submit(worker);

返回值map在这种情况下是 Future .这意味着它没有值,直到可调用对象返回一个值。现在当你打电话时

                    iTextRecords.putAll(map.get());

发生的情况是当前线程阻塞(在 map.get() 内)等待可调用对象返回(在另一个线程中)。

由于您总是在提交新的调用(根据 map.get() )之前等待完成调用(根据 executor.submit() ),因此您强制执行观察到的顺序执行。

为了并行执行任务,您必须在第一次调用 get 之前启动它们。例如,您可以创建一个 ArrayList<Future<Map<String,String>>> futures = ...进而做

  futures.add(executor.submit(worker)); 

提交任务(不需要 map 变量)并创建第二个循环(在 for(int i ...) 循环之后):

 for(Future<Map<String,String>> f: futures) {
iTextRecords.putAll(f.get);
}

关于java - 使用 java Executor 接口(interface)的多线程方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19049770/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com