Java ArrayList线程安全测试代码失败

Java ArrayList线程安全测试代码失败,java,multithreading,collections,thread-safety,arraylist,Java,Multithreading,Collections,Thread Safety,Arraylist,给定,在ArrayList中添加方法定义如下所示:- public boolean add(E e) { ensureCapacity(size + 1); // Increments modCount!! elementData[size++] = e; return true; } 请查找以下程序以检查ArrayList的线程安全性 package pack4; import java.util.ArrayList; public class Demo { public s

给定,在ArrayList中添加方法定义如下所示:-

public boolean add(E e) {
ensureCapacity(size + 1);  // Increments modCount!!
elementData[size++] = e;
return true;
}
请查找以下程序以检查ArrayList的线程安全性

package pack4;

import java.util.ArrayList;

public class Demo {

    public static void main(String[] args) {
        ArrayList<String> al = new ArrayList<String>() ;
        new AddFirstElementThread(al).start() ;
        new RemoveFirstElementThread(al).start() ;
    }
}

class AddFirstElementThread extends Thread{

    ArrayList<String> list ;

    public AddFirstElementThread(ArrayList<String> l) {
        list = l ;
    }

    @Override
    public void run() {
        while(true){
            if(list.size() == 0){
                list.add("First element") ;
            }
        }
    }
}

class RemoveFirstElementThread extends Thread{

    ArrayList<String> list ;

    public RemoveFirstElementThread(ArrayList<String> l) {
        list = l ;
    }

    @Override
    public void run() {
        while(true){
            if(list.isEmpty()){
                try{
                    list.get(0) ;
                    System.out.println("Hence Proved, that ArrayList is not Thread-safe.");
                    System.exit(1) ;
                }catch (Exception e) {
                        //continue, if no value is there at index 0
                }
            }
        }
    }
}
pack4;
导入java.util.ArrayList;
公开课演示{
公共静态void main(字符串[]args){
ArrayList al=新的ArrayList();
新的AddFirstElementThread(al.start();
新建RemoveFirstElementThread(al.start();
}
}
类AddFirstElementThread扩展线程{
数组列表;
公共AddFirstElementThread(ArrayList l){
列表=l;
}
@凌驾
公开募捐{
while(true){
if(list.size()==0){
列表。添加(“第一要素”);
}
}
}
}
类RemoveFirstElementThread扩展线程{
数组列表;
public RemoveFirstElementThread(ArrayList l){
列表=l;
}
@凌驾
公开募捐{
while(true){
if(list.isEmpty()){
试一试{
list.get(0);
println(“因此证明,ArrayList不是线程安全的。”);
系统出口(1);
}捕获(例外e){
//如果索引0处没有值,则继续
}
}
}
}
}
但是,程序从不终止,因此无法证明ArrayList的线程安全性

package pack4;

import java.util.ArrayList;

public class Demo {

    public static void main(String[] args) {
        ArrayList<String> al = new ArrayList<String>() ;
        new AddFirstElementThread(al).start() ;
        new RemoveFirstElementThread(al).start() ;
    }
}

class AddFirstElementThread extends Thread{

    ArrayList<String> list ;

    public AddFirstElementThread(ArrayList<String> l) {
        list = l ;
    }

    @Override
    public void run() {
        while(true){
            if(list.size() == 0){
                list.add("First element") ;
            }
        }
    }
}

class RemoveFirstElementThread extends Thread{

    ArrayList<String> list ;

    public RemoveFirstElementThread(ArrayList<String> l) {
        list = l ;
    }

    @Override
    public void run() {
        while(true){
            if(list.isEmpty()){
                try{
                    list.get(0) ;
                    System.out.println("Hence Proved, that ArrayList is not Thread-safe.");
                    System.exit(1) ;
                }catch (Exception e) {
                        //continue, if no value is there at index 0
                }
            }
        }
    }
}
请建议正确的实现来测试ArrayList和Vector的线程安全行为

谢谢并致以最良好的问候


Rits

阵列列表
不是线程安全的<代码>矢量为。如果需要,您可以将
ArrayList
集合打包。synchronizedList()

ArrayList
不是线程安全的<代码>矢量为。如果需要,可以将
ArrayList
Collections.synchronizedList()
包装在一起。

对于绝大多数情况,从集合的“线程安全”开始是一个非常糟糕的主意,因为它太窄了,而且无论如何都需要更高级别的同步

如果您真的想删除第一个元素或向列表中添加一个元素,您最好使用例如,但您设计的示例无论如何可能需要更高的同步(取决于语义到底应该是什么-如果您不明白为什么,阅读一些关于并发性的内容可能是一个非常好的主意)

最后,请看一看集合上的“线程安全性”对于绝大多数情况来说是一个非常糟糕的主意,因为它太窄了,而且无论如何都需要更高级别的同步

如果您真的想删除第一个元素或向列表中添加一个元素,您最好使用例如,但您设计的示例无论如何可能需要更高的同步(取决于语义到底应该是什么-如果您不明白为什么,阅读一些关于并发性的内容可能是一个非常好的主意)


最后,请看一下。

关于不安全代码的一点是,无法保证在使用多个线程时它的行为。您不能保证不安全代码会失败。这是因为编写的代码不是不安全的,它可能无法保证它是安全的。线程安全性只能通过阅读和理解代码来确定


线程安全性的问题在于很难通过实验证明。要证明某些东西不是线程安全的并不容易,除非您知道触发问题的确切边缘情况。此外,根据系统的体系结构和负载,线程安全问题或多或少会出现。i、 它可以在几天内正常工作,并且会意外失败

关于不安全代码的要点是,无法保证在使用多线程时它的行为。您不能保证不安全代码会失败。这是因为编写的代码不是不安全的,它可能无法保证它是安全的。线程安全性只能通过阅读和理解代码来确定


线程安全性的问题在于很难通过实验证明。要证明某些东西不是线程安全的并不容易,除非您知道触发问题的确切边缘情况。此外,根据系统的体系结构和负载,线程安全问题或多或少会出现。i、 它可以在几天内正常工作,并且会意外失败

谢谢你的快速回复。但我只是想为这个写一个测试用例。:)为什么?难道你不认为作者知道如何使收集线程安全吗?我通常不测试核心类。实际上,我是一个线程新手。只是探索基本原理。@RIT您试图测试的行为没有实现。这样的测试是什么样的?谢谢你的快速回复。但我只是想为这个写一个测试用例。:)为什么?难道你不认为作者知道如何使收集线程安全吗?我通常不测试核心类。实际上,我是一个线程新手。只是探索基本原理。@RIT您试图测试的行为没有实现。这样的测试是什么样的?嗯,那是
ArrayList
不是线程安全的,因此您首先无法测试它。当然,这种情况永远不会终止,您没有终止条件。如果您正在编写一个测试用例,那么应该有一些终止条件。当(true){do stuff}在每一个线程中时,这两个线程都会永远运行。@Milhous:RemoveFirstElementThread的run方法中有一个终止条件……只有在RemoveFirstElement线程第一次进入调用时列表为空时,它才会终止。否则它将永远运行。好吧,那就是
ArrayList
不是线程安全的,因此您无法首先测试它。当然,这种情况永远不会终止,您没有终止条件