gpt4 book ai didi

java - 没有从提交给线程池的作业中获得任何输出

转载 作者:行者123 更新时间:2023-11-30 07:26:19 24 4
gpt4 key购买 nike

假设我有 A 类和 B 类。A 类只有一个主要方法,代码如下:

public class A{
public static void main(String[] args){
String xput = "";
ExecutorService pool = Executors.newFixedThreadPool(4);
for(int i = 1; i < number; i++){
pool.submit(new B(list.get(i-1)));
xput = B.returnValue;
System.out.println(xput);//testing purposes
}
}
}

B 类扩展了线程,看起来像这样:

public class B extends Thread{

static String returnValue = "";

public B(String x){
super(x);
}

public void run(){
double x = 20;
returnValue += "Grand total: " +
NumberFormat.getCurrencyInstance().format(x) + "\n";
}
}

然而 System.out.println(xput) 除了一个空行之外没有打​​印任何东西。有人知道为什么吗?我的类(class)显然有比这更多的代码,但由于我没有得到任何输出,所以我从一个小案例开始。

最佳答案

此代码存在许多竞争条件,因为它们都更新相同的 static String returnValue。此外,当 System.out.println(xput) 被调用时,线程实际上可能还没有运行。您需要使用 future.get() 方法来等待每个线程完成,您不能在将它们提交到线程池的同一循环中执行此操作。

由于 4 个线程将同时运行,并且它们都在更新相同的 static 字段,因此您需要围绕该变量提供一些同步。我建议改为使用 ExecutorServiceFuture 功能,而不是修改静态字段。像下面这样的东西应该可以工作:

List<Future<String>> futures = new ArrayList<Future<String>>();
for(int i = 1; i < number; i++){
B b = new B(list.get(i - 1));
// submit the job b add the resulting Future to the list
futures.add(pool.submit(b));
}
// all of the jobs are submitted now
StringBuilder sb = new StringBuilder();
for (Future<String> future : futures) {
// now join with each of the jobs in turn and get their return value
sb.append(future.get());
}
System.out.println(sb.toString());

// you should implement Callable _not_ extend thread
public class B implements Callable<String> {
public String call(){
...
return "some string";
}
}

ExecutorServiceFuture 功能允许您从线程池处理的每个作业中获取结果。您可以使用 submit() Callable 类,它可以从 call() 返回结果 String(或其他对象) > 方法。

此外,您的 B 应该实现 Callable 而不是扩展 Thread。尽管它可以工作,但这只是因为 Thread 也实现了 Runnable。线程池有自己的内部线程,您只需向它提交 RunnableCallable 对象。

最后,在处理列表(或任何 Java 集合)时不要使用 for (int i 循环,您应该养成使用的习惯:

 for(String x : list) {
B b = new B(x);
...

如果您必须使用 for (int i 然后至少从 0 到列表的 size():

 for(int i = 0; i < list.size(); i++) {

这样,如果您更改列表的大小,您就不必记住也要更改循环。

关于java - 没有从提交给线程池的作业中获得任何输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10399272/

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