Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.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/6/multithreading/4.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
Java ArrayList中的异常示例?_Java_Multithreading_Collections - Fatal编程技术网

Java ArrayList中的异常示例?

Java ArrayList中的异常示例?,java,multithreading,collections,Java,Multithreading,Collections,我正在使用ArrayList,我想要一个异常示例,以防多个线程试图在不同步的情况下访问同一个列表?我在单线程应用程序中做到了这一点,在这个应用程序中,如果我们在迭代时从列表中删除一个元素,它会抛出ConcurrentModificationExceptoin,但我希望在多线程环境中实现同样的效果。如果有人能给我举个例子,我将不胜感激 package com.test2; public class ThreadTest extends Thread { List list = new

我正在使用ArrayList,我想要一个异常示例,以防多个线程试图在不同步的情况下访问同一个列表?我在单线程应用程序中做到了这一点,在这个应用程序中,如果我们在迭代时从列表中删除一个元素,它会抛出ConcurrentModificationExceptoin,但我希望在多线程环境中实现同样的效果。如果有人能给我举个例子,我将不胜感激

package com.test2;

public class ThreadTest extends Thread {

    List list = new ArrayList<String>();

    @Override
    public void run() {

        list.add("1");
        list.add("2");
        list.add("3");
        list.add("4");
        list.add("5");
        try {
            Thread.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        list.add("6");
        list.add("7");
        list.add("8");

        Iterator<String> it = list.iterator();
        while (it.hasNext()) {
            System.out.println(it.next());
        }

    }

    public static void main(String[] args) {



        Thread th1 = new ThreadTest();
        Thread th2 = new ThreadTest();
        Thread th3 = new ThreadTest();
        th1.start();
        th2.start();
        th3.start();
        try {
            th1.join();
            th2.join();
            th3.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }




    }

}
package com.test2;
公共类ThreadTest扩展了线程{
列表=新的ArrayList();
@凌驾
公开募捐{
列表。添加(“1”);
列表。添加(“2”);
列表。添加(“3”);
列表。添加(“4”);
列表。添加(“5”);
试一试{
睡眠(1);
}捕捉(中断异常e){
e、 printStackTrace();
}
列表。添加(“6”);
列表。添加(“7”);
列表。添加(“8”);
Iterator it=list.Iterator();
while(it.hasNext()){
System.out.println(it.next());
}
}
公共静态void main(字符串[]args){
螺纹th1=新螺纹测试();
螺纹th2=新螺纹测试();
螺纹th3=新螺纹测试();
th1.start();
th2.start();
th3.start();
试一试{
th1.join();
th2.join();
th3.join();
}捕捉(中断异常e){
e、 printStackTrace();
}
}
}

如果我理解您的问题,请更改此选项

List list = new ArrayList<String>();
从javadoc

返回由指定列表支持的同步(线程安全)列表。为了保证串行访问,通过返回的列表完成对备份列表的所有访问至关重要

用户在对返回的列表进行迭代时,必须手动同步该列表:

List list = Collections.synchronizedList(new ArrayList());
...
synchronized (list) {
  Iterator i = list.iterator(); // Must be in synchronized block
  while (i.hasNext())
    foo(i.next());
  }
}
它抛出ConcurrentModificationExceptoin,但我希望在多线程环境中实现同样的效果

我问的是如何在多线程环境中从注释中获取异常

由于您正在为每个线程创建单独的
列表副本
,因此没有机会获得此异常

只需将
列表
设置为共享资源,您就会遇到此异常:

示例代码:

public class Main{

    public static void main(String[] args){

        // shared by all the threads.
        final List<String> list = new ArrayList<String>();
        
        class ThreadTest extends Thread {


            @Override
            public void run() {

                list.add("1");
                list.add("2");
                list.add("3");
                list.add("4");
                list.add("5");
                try {
                    Thread.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                list.add("6");
                list.add("7");
                list.add("8");

                Iterator<String> it = list.iterator();
                while (it.hasNext()) {
                    System.out.println(it.next());
                }

            }
        }

        Thread th1 = new ThreadTest();
        Thread th2 = new ThreadTest();
        Thread th3 = new ThreadTest();
        th1.start();
        th2.start();
        th3.start();
        try {
            th1.join();
            th2.join();
            th3.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
快速回答:

public class Main {

    public static void main(String[] args) throws InterruptedException
    {
        final ArrayList<String> list = new ArrayList<String>();
        list.add("Item 1");
        list.add("Item 2");
        list.add("Item 3");
        list.add("Item 4");

        Thread thread = new Thread(new Runnable()
        {
            @Override
            public void run ()
            {
                for (String s : list)
                {
                    System.out.println(s);
                    try
                    {
                        Thread.sleep(1000);
                    }
                    catch (InterruptedException e)
                    {
                        e.printStackTrace();
                    }
                }
            }
        });
        thread.start();

        Thread.sleep(2000);
        list.remove(0);
    }
}
注:
正如@Braj和@DaoWen所说,您使用的是不同的实例。使用他们的建议,或者在类的构造函数(ThreadTest)中传递list变量。

您正在访问每个线程中的一个单独的list实例。由于每个列表仅由一个线程访问,因此不能获得并发错误

List list = new ArrayList<String>();
至于错误是如何发生的,请查看:

如果两个线程同时调用
add
,它们可以同时处理
elementData[size++]=e
语句;因此,这两个线程可能最终写入
elementData
数组中的同一索引

即使
size
被声明为
volatile
size++
操作也不是原子操作。有关类似于
size++
的操作如何在多线程环境中失败的示例,请参阅


最后,如果您不理解Java上下文中的
volatile
和atomic是什么意思,那么在编写任何多线程代码之前,您确实需要阅读Java中的并发编程。这将是一项值得投资的投资,因为理解这些概念会让你省去很多麻烦。

最好也分享你的代码。你是在问如何解决这个ConcurrentModificationExceptoin问题吗?Braj:我是在问如何在多线程环境中获得异常,就像在单线程环境中一样environment.you可能需要一个(int i=0;它有很多道文。在添加静态之后,我遇到了异常。Braj:你能告诉我你在哪里声明你的列表吗?就在类
ThreadTest
之外以使它共享资源。我担心我们可以在Java中声明类之外的列表。这会导致编译错误。你确定我们可以在类之外声明列表吗用Java编写类?不知道你是怎么做的,我已经共享了一个运行的代码。感谢Elliott Frisch的代码,但我正在尝试获取一个异常。我正在对Java文档执行POC语句“如果我们在多线程环境中使用ArrayList,我们将获得一个并发异常。”
public class Main {

    public static void main(String[] args) throws InterruptedException
    {
        final ArrayList<String> list = new ArrayList<String>();
        list.add("Item 1");
        list.add("Item 2");
        list.add("Item 3");
        list.add("Item 4");

        Thread thread = new Thread(new Runnable()
        {
            @Override
            public void run ()
            {
                for (String s : list)
                {
                    System.out.println(s);
                    try
                    {
                        Thread.sleep(1000);
                    }
                    catch (InterruptedException e)
                    {
                        e.printStackTrace();
                    }
                }
            }
        });
        thread.start();

        Thread.sleep(2000);
        list.remove(0);
    }
}
Item 1
Item 2
Exception in thread "Thread-0" java.util.ConcurrentModificationException
    at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:859)
    at java.util.ArrayList$Itr.next(ArrayList.java:831)
    at com.akefirad.tests.Main$1.run(Main.java:34)
    at java.lang.Thread.run(Thread.java:745)
List list = new ArrayList<String>();
static List list = new ArrayList<String>();
 public boolean add(E e) {
     ensureCapacityInternal(size + 1);  // Increments modCount!!
     elementData[size++] = e;
     return true;
 }