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