知识大全 多线程中使用Java集合类
Posted 元素
篇首语:追风赶月莫停留,平芜尽处是春山。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 多线程中使用Java集合类相关的知识,希望对你有一定的参考价值。
多线程中使用Java集合类 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
Java集合类中 某个线程在 Collection 上进行迭代时 通常不允许另一个线性修改该 Collection 通常在这些情况下 迭代的结果是不确定的 如果检测到这种行为 一些迭代器实现(包括 JRE 提供的所有通用 collection 实现)可能选择抛出此异常 执行该操作的迭代器称为快速失败 迭代器 因为迭代器很快就完全失败 而不会冒着在将来某个时间任意发生不确定行为的风险
因此 当一个线程试图ArrayList的数据的时候 另一个线程对ArrayList在进行迭代的 会出错 抛出ConcurrentModificationException
比如下面的代码
final List<String> tickets = new ArrayList<String>();
for (int i = ; i < ; i++)
tickets add( ticket NO + i);
System out println( start );
for (int i = ; i < ; i++)
Thread salethread = new Thread()
public void run()
while (tickets size() > )
tickets remove( );
System out println(Thread currentThread() getId()+ Remove );
;
salethread start();
System out println( start );
new Thread()
public void run()
for (String s : tickets)
System out println(s);
start();
上述程序运行后 会在某处抛出异常
java util ConcurrentModificationException
at java util ArrayList$Itr checkForComodification(Unknown Source)
at java util ArrayList$Itr next(Unknown Source)
at mytest mytestpkg Tj$ run(Tj java: )
Vector是线程同步的 那么把ArrayList改成Vector是不是就对了呢?
答案是否定的 事实上 无论是ArrayList还是Vector 只要是实现Collection接口的 都要遵循fail fast的检测机制 即在迭代是时候 不能修改集合的元素 一旦发现违法这个规定就会抛出异常
事实上 Vector相对于ArrayList的线程同步 体现在对集合元素是否脏读上 即ArrayList允许脏读 而Vector特殊的机制 不会出现脏读 但是效率会很差
举个例子 一个集合 有 个线程从该集合中删除元素 那么每个元素只可能由一个线程删除掉 不可能会出现一个元素被多个线程删除的情况
比如下面的代码
final List<String> tickets = new ArrayList<String>();
for (int i = ; i < ; i++)
tickets add( ticket NO + i);
System out println( start );
for (int i = ; i < ; i++)
Thread salethread = new Thread()
public void run()
while (true)
if(tickets size()> )
System out println(Thread currentThread() getId()+ tickets remove( ));
else
break;
;
salethread start();
for循环构造 个线程删除同一个集合中的数据 理论上只能删除 次 但是运行完发现 输出的删除次数 次 其中很多数据都是被多个线程删除 比如下面的输出片段
ticket NO
ticket NO
ticket NO
ticket NO
ticket NO
ticket NO
ticket NO
ticket NO
ticket NO
ticket NO
ticket NO
可以看到 都被多个线程删除 这事实上就是出现了脏读 解决的办法就是加锁 使得同一时刻只有 个线程对ArrayList做操作
修改代码 synchronized关键字 让得到锁对象的线程才能运行 这样确保同一时刻只有一个线程操作集合
final List<String> tickets = new ArrayList<String>();
for (int i = ; i < ; i++)
tickets add( ticket NO + i);
System out println( start );
final Object lock=new Object();
for (int i = ; i < ; i++)
Thread salethread = new Thread()
public void run()
while (true)
synchronized(lock)
if(tickets size()> )
System out println(Thread currentThread() getId()+ tickets remove( ));
else
break;
;
salethread start();
这样得到的结果就是准确的了
当然 不使用synchronized关键字 而直接使用vector或者Collections synchronizedList 也是同样效果
final List<String> tickets =java util Collections synchronizedList(new ArrayList<String>());
final List<String> tickets =new Vector<String>();
cha138/Article/program/Java/gj/201311/27405相关参考
知识大全 Java多线程系列--“JUC原子类”05之 AtomicLongFieldUpdater原子类
Java多线程系列--“JUC原子类”05之AtomicLongFieldUpdater原子类 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整
java多线程之wait()notify()notifyAll() wait()notify()notifyAll()不属于Thread类而是属于Object基础类也就是说每个对像都有wait(
二回调 轮询方法最大的特点是主类Main不断询问线程类是否结束这实际上大量浪费了运行时间特别是当线程特别多的时候因此如果反过来在线
在java多线程程序中所有线程都不允许抛出未捕获的checkedexception也就是说各个线程需要自己把自己的checkedexception处理掉这一点是通过javalangRunnable
知识大全 java多线程中synchronized关键字的用法
由于同一进程内的多个线程共享内存空间在Java中就是共享实例当多个线程试图同时修改某个实例的内容时就会造成冲突因此线程必须实现共享互斥使多线程同步 最简单的同步是将一个方法标记为synchron
JAVA多线程中的锁机制 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! JAVA中的每个对象都可
Java程序中的多线程 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 一为什么会排队等待? 下
Java程序中的多线程(四) 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 作者NeelVKum
Java程序中的多线程(二) 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 作者NeelVKum
Java程序中的多线程(一) 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 作者NeelVKum