java集合的同步测试

xienue 2012-07-07

前不久在给web项目做一个工具包,安全审计。

响应领导号召,为了提高效率不用线程安全的java集合,用如arraylist这样线程不安全的集合,而且自己不加线程控制,哪个servlet都可以向arraylist添加一条记录。

可是在下,怎么想都会有问题,所以多了一个超简单的demo,代码如下:

public static void main(String[] args)
	{
		final ArrayList<String> list = new ArrayList<String>();
		ExecutorService exec = Executors.newCachedThreadPool();
		for(int i=0;i<20000;i++)
		{
			Thread t = new Thread(new Runnable()
			{
				
				@Override
				public void run()
				{
					// TODO Auto-generated method stub
//					synchronized (list)
//					{
						list.add("name");
//					}
//					System.out.println("add1");
					try
					{
						Thread.sleep(100);
					}
					catch (InterruptedException e)
					{
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
//					synchronized (list)
//					{
						list.add("name2");
//					}
//					System.out.println("add2");
				}
			}, i+"name");
			exec.execute(t);
		}

		try
		{
			Thread.sleep(10000);
		}
		catch (InterruptedException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println("最终添加记录条数:"+list.size());
}

 结果,最终添加记录条数本应该为40000条,实际上是39900多条,总是差个几十条,但是jvm也不报错。

 当我把上边那个超简单的demo的synchronized语句打开时,结果为40000条,正确。

 不知道jvm是怎么实现滴,看了源码后,感觉是这样滴:

        添加记录的add方法,无非也是用index添加到集合中,当多线程同时添加时,假设index为10,第一条线程添加到index为10的值为chineseAV,但是index还没有加一的说,第二条记录就把index为10的值改为japaneseAV。所以导致最终记录数不对问题。

不知道删除集合的时候,不做线程控制会不会报错呢,结果是否正确(肯定有问题啊!!领导!!你就坑爹吧!!)

未完,接着本人测试一下其他集合,也希望各位大侠帮忙,分享下集合多线程的经验,不要让小弟挨个集合测试,

所以如果不同步锁的话,肯定会造成链表连接混乱,所以add过程都共享并改变资源header(linkedlist的标志节点)(领导!!你就坑爹吧!!)

相关推荐