java 8中通过remove方法返回相同对象的java arraylist
我有两个线程共享同一个列表,第一个线程在列表中添加新对象,第二个线程在同一个列表上执行删除。在启动两个线程一段时间后,我得到了相同的对象,为什么和如何 JAVA代码: SubmitJob将线程运行类添加到列表中java 8中通过remove方法返回相同对象的java arraylist,java,multithreading,arraylist,synchronization,Java,Multithreading,Arraylist,Synchronization,我有两个线程共享同一个列表,第一个线程在列表中添加新对象,第二个线程在同一个列表上执行删除。在启动两个线程一段时间后,我得到了相同的对象,为什么和如何 JAVA代码: SubmitJob将线程运行类添加到列表中 public class SubmitJob extends Thread{ public SubmitJob(List l){ list = l; } List<ThreadRuning> list; private sta
public class SubmitJob extends Thread{
public SubmitJob(List l){
list = l;
}
List<ThreadRuning> list;
private static int counter =0;
public void run(){
while(true){
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ThreadRuning t = new ThreadRuning();
t.setThreadname("Thread Name "+counter);
t.setStarttime(new Date().getTime());
list.add(t);
//System.out.println("Submited"+t.getThreadname());
counter++;
}
}
}
ThreadRuning
class:
public class ThreadRuning extends Thread{
private long starttime;
private String threadname;
public void run(){
for(int i=0;i<10;i++){
//System.out.println("Name of Thread "+threadname+ "Executing times"+i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
// getter setter.
}
公共类线程运行扩展线程{
私人长启动时间;
私有字符串threadname;
公开募捐{
对于(inti=0;i,除了尝试在ArrayList的并发环境中工作之外,还应该真正了解Java中的引用
if (list.size()>0) {
ThreadRuning t = list.remove(0);
System.out.println(t.getState()+" name "+t.getThreadname());
if(t!=null)t.start();
//System.out.println("Startinf job"+t.getThreadname());
}
该方法返回已删除的对象。它不会创建该对象的新实例。这就是为什么当您再次尝试启动线程时,会出现IllegalThreadStateException
。除了尝试在ArrayList的并发环境中工作之外,您还应该真正了解Java中的引用
if (list.size()>0) {
ThreadRuning t = list.remove(0);
System.out.println(t.getState()+" name "+t.getThreadname());
if(t!=null)t.start();
//System.out.println("Startinf job"+t.getThreadname());
}
该方法返回已删除的对象。它不会创建该对象的新实例。这就是为什么当您再次尝试启动线程时,会出现IllegalThreadStateException
。当您共享一个对象时,它需要是线程安全的,以避免导致难以修复的错误的不可预知的行为。这里是您的共享ArrayList
这不是线程安全的,您应该使用线程安全的集合。如果您确实需要列表
,只需使用装饰器集合。synchronizedList(List)
作为下一步:
List<ThreadRuning> list = Collections.synchronizedList(new ArrayList<ThreadRuning>());
new SubmitJob(list).start();
new JobMoniter(list).start();
List List=Collections.synchronizedList(新的ArrayList());
新提交作业(列表).start();
新建作业监视器(列表).start();
然而,队列
似乎更合适,ConcurrentLinkedQueue
(这是一种本机线程安全的队列
实现)在这里可能是一个不错的选择。当您共享对象时,它需要是线程安全的,以避免导致难以修复的错误的不可预知的行为。在这里,您共享的数组列表不是线程安全的,您应该使用线程安全的集合。如果您确实需要列表
,只需使用decorator集合即可ns.synchronizedList(列表)
如下所示:
List<ThreadRuning> list = Collections.synchronizedList(new ArrayList<ThreadRuning>());
new SubmitJob(list).start();
new JobMoniter(list).start();
List List=Collections.synchronizedList(新的ArrayList());
新提交作业(列表).start();
新建作业监视器(列表).start();
然而,队列
似乎更合适,ConcurrentLinkedQueue
(这是一种本机线程安全的队列
实现)在这里可能是一个不错的选择。ArrayList
不是线程安全的。如果您从两个单独的线程中修改它而不使用同步,它的行为将不可预测。ArrayList
不是线程安全的。它在中的含义非常明确。您必须同步或使用更合适的数据结构,如队列。ArrayListt
不是线程安全的。如果您从两个单独的线程修改它而不使用同步,它的行为将不可预测。ArrayList
不是线程安全的。它在中的说明非常响亮和清晰。您必须同步或使用更合适的数据结构,如队列。谢谢您的回答。我知道为什么IllegalThreadStateException
是来的。它只有当remove方法返回相同的对象时才会来,是吗?谢谢你的回答。我知道为什么IllegalThreadStateException
会来。它只有当remove方法返回相同的对象时才会来,是吗?谢谢Nicolas,我的问题已经在你的建议之后了。谢谢Nicolas,我的问题已经在你的建议之后了。