Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/319.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2008/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Can';我从Java共享ArrayList中删除元素,同时向其中添加元素_Java_Arraylist_Synchronized - Fatal编程技术网

Can';我从Java共享ArrayList中删除元素,同时向其中添加元素

Can';我从Java共享ArrayList中删除元素,同时向其中添加元素,java,arraylist,synchronized,Java,Arraylist,Synchronized,首先,我这里没有使用迭代器 我在一个共享的ArrayList上使用了两个线程,第一个线程用于向ArrayList中添加值,另一个线程用于创建ArrayList的临时副本并对其执行一些操作,然后从原始列表中删除所有临时元素 import java.util.ArrayList; import java.util.Arrays; import java.util.List; public class ArraylistTest { public static void main(Stri

首先,我这里没有使用迭代器

我在一个共享的ArrayList上使用了两个线程,第一个线程用于向ArrayList中添加值,另一个线程用于创建ArrayList的临时副本并对其执行一些操作,然后从原始列表中删除所有临时元素

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class ArraylistTest {

    public static void main(String...ar){
        new AddingThread().start();
        new RemovalThread().start();
    }
}

class RemovalThread extends Thread{
    static List<Integer> originalBigList = new ArrayList<>();

    @Override
    public void run(){
        System.out.println("RemovalThread started");
        while(true){
            try {
                sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("creating copy of originalBigList");
            List<Integer> tempList = new ArrayList<>(originalBigList);
            System.out.println("copied list");
            //
            //some operations on copied temp list
            //
            System.out.println("removing tempList elements after completing operations");
            System.out.println("originalBigList before removing size "+originalBigList.size());
            originalBigList.removeAll(tempList);
            System.out.println("removed!!");
            System.out.println("after size "+originalBigList.size());
        }
    }
}

class AddingThread extends Thread{

    @Override
    public void run(){
        System.out.println("Adding thread started");
        int ctr = 0;
        while(true){
            RemovalThread.originalBigList.add(ctr);
            ctr++;
        }
    }
}
现在我的问题是,我在输出中看到,复制列表的语句被执行,从原始列表生成临时列表,但是删除语句没有执行,也没有给出任何异常,我使用的是简单的arraylist not Synchronized,为什么会这样

是否有任何内部锁定打开“移除”或“添加”操作?如果是,那么Collections.Synchronized(arraylist)的用途是什么

            List<Integer> tempList = new ArrayList<>(originalBigList);
List templast=newarraylist(originalBigList);
将在列表构造器中通过originalBigList迭代来创建您的模板列表,如果AddingRead将并行运行,它将抛出ConcurrentModificationException,杀死您的RemovalThread可能您在控制台中看不到它,但它可能在那里。我建议使用CopyOnWriteArrayList作为您的原始英语

            List<Integer> tempList = new ArrayList<>(originalBigList);
List templast=新ArrayList(Originabligst);

将在列表构造器中通过originalBigList迭代来创建您的模板列表,如果AddingRead将并行运行,它将抛出ConcurrentModificationException,杀死您的RemovalThread可能您在控制台中看不到它,但它可能在那里。我建议使用CopyOnWriteArrayList作为您的原始英语

我发现了您的问题请查看以下代码

 public static void main(String ...args){
    long start = System.currentTimeMillis();
    List<Integer> l1 = new ArrayList<>();
    List<Integer> l2 = new ArrayList<>();

    for(int i = 0 ; i < Integer.MAX_VALUE/10000;i++){
        l1.add(i);
        l2.add(i);
    }

    System.out.println(String.format("Field both arrays in %s seconds",(System.currentTimeMillis()-start)/1000) );
    start = System.currentTimeMillis();
    l1.removeAll(l2);

    System.out.println(String.format("Removed one array from other %s seconds",(System.currentTimeMillis()-start)/1000) );

}
}


}

我发现了您的问题请查看以下代码

 public static void main(String ...args){
    long start = System.currentTimeMillis();
    List<Integer> l1 = new ArrayList<>();
    List<Integer> l2 = new ArrayList<>();

    for(int i = 0 ; i < Integer.MAX_VALUE/10000;i++){
        l1.add(i);
        l2.add(i);
    }

    System.out.println(String.format("Field both arrays in %s seconds",(System.currentTimeMillis()-start)/1000) );
    start = System.currentTimeMillis();
    l1.removeAll(l2);

    System.out.println(String.format("Removed one array from other %s seconds",(System.currentTimeMillis()-start)/1000) );

}
}


}

与@urag的答案类似(特别是关于O(n²)的注释),您可以通过修改
添加read
like来查看效果,因此它只添加了有限数量的项:

class AddingThread extends Thread{

    @Override
    public void run(){
        System.out.println("Adding thread started");
        int ctr = 0;
        while(true){

          if (ctr < 100_000) {
            RemovalThread.originalBigList.add(ctr);
            ctr++;
           }
      }
  }
}
现在,将
100_000
更改为
1_000_000
,您将等待很长时间,只看到:

Adding thread started
RemovalThread started
creating copy of originalBigList
copied list
removing tempList elements after completing operations
originalBigList before removing size 1000000

与@urag的答案类似(特别是关于O(n²)的注释),您可以通过修改
addingread
like来查看效果,因此它只添加了有限数量的项:

class AddingThread extends Thread{

    @Override
    public void run(){
        System.out.println("Adding thread started");
        int ctr = 0;
        while(true){

          if (ctr < 100_000) {
            RemovalThread.originalBigList.add(ctr);
            ctr++;
           }
      }
  }
}
现在,将
100_000
更改为
1_000_000
,您将等待很长时间,只看到:

Adding thread started
RemovalThread started
creating copy of originalBigList
copied list
removing tempList elements after completing operations
originalBigList before removing size 1000000


ArrayList不是线程安全的?2分钟内对该问题投2票?是的,这看起来不像是投票欺诈。嘿,汤姆,为什么会有-1评级,我只是问了一个有效的问题…ArrayList不是线程安全的?2分钟内对该问题投2票?是的,这看起来不像是选举舞弊。嘿,汤姆,为什么有-1评级,我只是问了一个有效的问题……我还以为它会根据Java文档给出ConcurrentModification异常,但它不会给出。我运行了几次这段代码,并且总是给出相同的输出。你怎么知道它没有呢?你没有试着将try catch放在内存中的所有块上,然后打印异常?因为,若在调试时执行此操作,它的行为可能会有所不同,我并没有放置try-catch,但若它发生,那个么JVM的运行时环境应该捕获它,并将在控制台中显示它。但事实并非如此,而且如果我使用CopyOnWriteArrayList,那么我有大量的写操作,因此每次写操作都会创建一个新的列表,我认为这是不可行的。请注意,迭代器的快速失效行为无法得到保证,因为一般来说,在存在非同步并发修改的情况下,不可能做出任何硬保证。快速失败迭代器会尽最大努力抛出ConcurrentModificationException。因此,编写依赖于此异常的正确性的程序是错误的:迭代器的快速失败行为应该只用于检测bug。“根据我提到的,我没有使用迭代器,请检查代码并尝试运行它,我从未遇到ConcurentModification异常。输出总是显示它无法执行remove命令,添加线程正在添加到originalListi我还认为它会根据Java文档给出ConcurrentModification异常,但它不会给出我运行了几次此代码,并且总是给出相同的输出。你怎么知道它没有尝试放置try catch在所有块的内部,同时打印异常?因为,若在调试时执行此操作,它的行为可能会有所不同,我并没有放置try-catch,但若它发生,那个么JVM的运行时环境应该捕获它,并将在控制台中显示它。但事实并非如此,而且如果我使用CopyOnWriteArrayList,那么我有大量的写操作,因此每次写操作都会创建一个新的列表,我认为这是不可行的。请注意,迭代器的快速失效行为无法得到保证,因为一般来说,在存在非同步并发修改的情况下,不可能做出任何硬保证。快速失败迭代器会尽最大努力抛出ConcurrentModificationException。因此,编写依赖于此异常的正确性的程序是错误的:迭代器的快速失败行为应该只用于检测bug。“根据我提到的,我没有使用迭代器,请检查代码并尝试运行它,我从未遇到ConcurentModification异常。输出总是显示它无法执行remove命令,并且添加线程正在添加到originAllistkanks Urag、Emre SevinçTkanks Urag、Emre Sevinç乐意帮助:)乐意帮助:)
Adding thread started
RemovalThread started
creating copy of originalBigList
copied list
removing tempList elements after completing operations
originalBigList before removing size 1000000