ArrayList ThreadSafety测试代码失败

时间:2011-07-16 20:51:22

标签: 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 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的线程安全性。

请建议正确的实现来测试ArrayList和Vector的线程安全行为。

谢谢&amp;最诚挚的问候,

RITS

3 个答案:

答案 0 :(得分:2)

ArrayList不是线程安全的; Vector是。如果需要,您可以使用ArrayList打包Collections.synchronizedList()

答案 1 :(得分:1)

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

线程安全问题是很难通过实验证明。除非你知道会引发问题的确切边缘情况,否则很难证明某些东西不是线程安全的。此外,线程安全问题或多或少可能会显示,具体取决于系统的体系结构及其负载。即它可以正常工作几天,并且无法预测地失败。

答案 2 :(得分:0)

对于绝大多数情况来说,收藏中的“线程安全”是一个非常糟糕的主意,因为它太狭窄了,无论如何你需要更高级别的同步。

如果你真的想要删除第一个元素或者将一个元素添加到列表中,那么最好使用例如this here,但是你设计的例子可能需要一些更高的同步(取决于究竟是什么)语义应该是 - 如果你不明白为什么,读一些关于并发的东西可能是个好主意)

最后只看一下concurrent framework