huayurei77 2011-08-01 01:13
浏览 2085
已采纳

java.util.Stack是线程安全的么?

最近在学习java的并发包编程,写了一段代码,模仿原来测试ArrayList非安全代码来测试java.util.Stack是否是线程安全的。代码如下:
[code="java"]
package concurrent.lock.alg;

import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

public class StackTest {
private static final int ELEMENT_NUM = 51180;
public static void main(String[] ben){
ExecutorService exec = Executors.newCachedThreadPool();
final Stack stackStr = new Stack();
for(int i=0;i<ELEMENT_NUM;++i){
exec.submit(new StackInsTask(stackStr));
}
exec.shutdown();
try{
exec.awaitTermination(500, TimeUnit.SECONDS);
}catch(InterruptedException e){
e.printStackTrace();
}

    List<String> testList = new ArrayList<String>();
    while(!stackStr.empty()){
        String dd = String.valueOf(stackStr.pop());
        //System.out.println(dd);
        testList.add(String.valueOf(dd));
    }
    //System.out.println(testList.size());
    for(int i=1;i<=ELEMENT_NUM;++i){
        if(!testList.contains(String.valueOf(i))){
            System.out.println("didn't find"+i);
        }
    }
}

}
class StackInsTask implements Runnable {
public static AtomicInteger count = new AtomicInteger();
Stack stack;

public StackInsTask(Stack s) {
    stack = s;
}

public void run() {
    stack.push(count.incrementAndGet());
}

}

[/code]
51180个线程同时启动,如果stack非安全,那么stack.push(count.incrementAndGet())插入的可能是同一个值。那么在:
[code="java"]
for(int i=1;i<=ELEMENT_NUM;++i){
if(!testList.contains(String.valueOf(i))){
System.out.println("didn't find"+i);
}
}
[/code]
[b]就会输出找不到的值,可是测试了几把发现好像是安全的,由于jdk也没说明stack是否是线程安全的,暂时没看源码,所以好奇来问下。顺便问下,eclipse看jdk源码需要下载些什么,这里偷个懒嘿嘿~[/b]

---------------------------------分割线,以下代码是证明ArrayList非安全的代码--------------------------------------
[code="java"]
package com.concurrent.Amino.List;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

public class CommonListTest {
private static final int ELEMENT_NUM = 28000;

public static void main(String[] argvs) {
    ExecutorService exec = Executors.newCachedThreadPool();

// final List listStr = new LockFreeList();
final List listStr = new ArrayList();
for (int i = 0; i < ELEMENT_NUM; ++i) {
exec.submit(new ListInsTask(listStr));
}

    exec.shutdown();

    try {
        exec.awaitTermination(500, TimeUnit.SECONDS);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

    System.out.println("Size of list is" + listStr.size());

    for (int i = 1; i <= ELEMENT_NUM; ++i) {
        if (!listStr.contains(i)) {
            System.out.println("didn't find " + i);
        }
    }
    System.out.println(ListInsTask.count.longValue());
}

}

class ListInsTask implements Runnable {
public static AtomicInteger count = new AtomicInteger();
List list;

public ListInsTask(List l) {
    list = l;
}

public void run() {
    if (list.add(count.incrementAndGet())) {
        //System.out.println("List Size = " + list.size());
    } else {
        System.out.println("did not insert" + count.get());
    }

}

}
[/code]

  • 写回答

1条回答 默认 最新

  • 也许世界还没停 2011-08-01 09:16
    关注

    Stack 继承自 Vector,是线程安全的
    似乎不太推荐这种老的容器了

    看源码这东西网上一搜一堆,就不转了

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 ubuntu虚拟机打包apk错误
  • ¥199 rust编程架构设计的方案 有偿
  • ¥15 回答4f系统的像差计算
  • ¥15 java如何提取出pdf里的文字?
  • ¥100 求三轴之间相互配合画圆以及直线的算法
  • ¥100 c语言,请帮蒟蒻写一个题的范例作参考
  • ¥15 名为“Product”的列已属于此 DataTable
  • ¥15 安卓adb backup备份应用数据失败
  • ¥15 eclipse运行项目时遇到的问题
  • ¥15 关于#c##的问题:最近需要用CAT工具Trados进行一些开发