以下是示例代码
1)ArrayList是一个传递给ThreadPool的每个线程的单个对象。
2)在执行结束时,列表大小应该是50,如果你检查样本输出它可能不是50。有时它可能是41或47那样,为什么它表现得那样。
public class Test {
ArrayList list=new ArrayList();
public static void main(String[] args) {
ExecutorService executorService3 = Executors.newScheduledThreadPool(10);
Test test=new Test();
for(int i=0;i<5;i++)
{
Mythread t1=new Mythread(test.list);
executorService3.execute(t1);
}
executorService3.shutdown();
while(executorService3.isShutdown())
{
//---This is not giveging proper output as expected is 50.--
System.out.println("List size="+test.list.size());
break;
}
}
}
class Mythread implements Runnable {
List list=null;
Mythread(List list) {
this.list=list;
}
@Override
public void run() {
for(int i=0;i<10;i++) {
this.list.add(i);
}
}
}
答案 0 :(得分:2)
您的代码不等待线程完成执行。当您的代码调用以下行
时System.out.println("List size="+test.list.size());
不保证他们已经完成,因此无法保证该列表包含预期的50个项目。使用awaitTermination方法(https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ExecutorService.html#awaitTermination(long,%20java.util.concurrent.TimeUnit)),例如:
executorService3.shutdown();
executorService3.awaitTermination(1, TimeUnit.SECONDS);
System.out.println("List size="+test.list.size());
(为简洁省略了异常处理)
答案 1 :(得分:2)
正如Javadoc for ArrayList
中所述:
请注意,此实施未同步。如果多个线程同时访问ArrayList实例,并且至少有一个线程在结构上修改了列表,则必须在外部进行同步。
所以&#34;不正常行为&#34;因为您没有按照文档中的说明使用它。
正如Javadoc中所建议的那样,您可以将list
包装在同步列表中:
List<Integer> list = Collections.synchronizedList(new ArrayList<>());
答案 2 :(得分:0)
这是一个并发问题。 我看到它的方式,你有: 5个线程将在同一个对象上执行run方法。多个线程可以在数组列表中的相同位置插入变量,因为它未同步。 你能打印清单的内容吗?