多线程使用Vector或HashTable
来源:互联网 发布:网红淘宝店货源 编辑:程序博客网 时间:2024/06/03 18:49
Vector是ArrayList的多线程版本,HashTable是HashMap的多线程版本,这些概念我 们都很清楚,也被前辈嘱咐过很多次,但我们经常会逃避使用Vector和HashTable,因为用 得少,不熟嘛!只有在真正需要的时候才会想要使用它们,但问题是什么时候算真正需要呢?我们来看一个例子,看看使用线程安全的Vector是否可以解决问题,代码如下:
<span style="font-size:18px;">//火车票列表final List<String> tickets = new java.util.ArrayList<String>();//初始化票据池for (int i = 0; i < 100000; i++) { tickets.add ( "火车票" + i);}//退票Thread returnThread = new Thread(){ public void run() {while (true) { tickets.add ("车票" +new Random().nextInt()); } };}; //售票Thread saleThread = new Thread(){public void run() {for (String ticket:tickets) { tickets.remove(ticket); } };};//启动退票线程returnThread.start(); //启动售票线程saleThread.start();</span>
模拟火车站售票程序,先初始化一堆火车票,然后开始出售,同时也有退票产生,这段程序有没有问题?可能会有读者看出了问题,ArrayList是线程不安全的,两个线程访问同一 个ArrayList数组肯定会有问题。
没错,确定有问题,运行结果如下:
Exception in thread "Thread-1"java.util.ConcurrentModificationBxception
at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372) atjava.util.AbstractList$Itr.next(AbstractList.java:343) atClient$2.run(Client.java:28)
运气好的话,该异常马上就会报出。也许有人会说这是一个典型错误,只须把ArrayList 替换成Vector即可解决问题,真的是这样吗?我们把ArrayList替换成Vector后,结果照旧,仍然抛出相同的异常,Vector已经是线程安全的,为什么还报这个错误呢?
这是因为他混淆了线程安全和同步修改异常,基本上所有的集合类都有一个叫做快速失败(Fail-Fast)的校验机制,当一个集合在被多个线程修改并访问时,就可能会出现 ConcurrentModificationException异常,这是为了确保集合方法一致而设置的保护措施,它 的实现原理就是我们经常提到的modCmmt修改计数器:如果在读列表时,modCount发生变 化(也就是有其他线程修改)则会抛出ConcurrentModificationException异常。这与线程同 步是两码事,线程同步是为了保护集合中的数据不被脏读、脏写而设置的,我们来看线程安 全到底用在什么地方,代码如下:
<span style="font-size:18px;">public static void main(String[] args) {//火车票列表final List<String> tickets = new java.util.ArrayList<String>();//初始化票据池for (int i = 0; i < 100000; i++) { tickets.add ( "火车票" + i);}for(int i=0;i<10;i++){new Thread(){@Overridepublic void run() {// TODO Auto-generated method stubwhile (true) {System.out.println(Thread.currentThread().getId()+"----"+tickets.remove(0));}}}.start();} }</span>
还是火车站售票程序,有10个窗口在卖火车票,程序打印出窗口号(也就是线程号)和车票编号,很快我们就会看到这样的输出:
13—火车票96531
10—火车票96531
9—火车票96530
16—火车票96530
注意看,上面有两个线程在卖同一张火车票,这才是线程不同步的问题,此时把ArrayList修改为Vector即可解决问题,因为Vector的每个方法前都加上了 synchronized关 键字,同时只会允许一个线程进入该方法,确保了程序的可靠性。
虽然在系统开发中我们一再说明,除非必要,否则不要使用synchronized,这是从性能 的角度考虑的,但是一旦涉及多线程时(注意这里说的是真正的多线程,不是并发修改的问 题,比如一个线程增加,一个线程删除,这不属于多线程的范畴),Vector会是最佳选择,当 然自己在程序中加synchronized也是可行的方法。
HashMap的线程安全类HashTable与此相同,不再赘述。
- 多线程使用Vector或HashTable
- Java_多线程_多线程使用Vector或HashTable
- Vector和Hashtable的使用:
- Vector ArrayList Hashtable的使用实例
- 多线程下:Vector、Hashtable、ArrayList、LinkedList、HashMap 性能特征
- 多线程集合Collections(Vector、Hashtable、ArrayList、LinkedList、HashMap )
- HashTable,HashMap/ArrayList,Vector
- java Vector and Hashtable
- vector和Hashtable
- Vector 和 HashTable
- 关于java.util.Vector 或 java.util.Hashtable类过时的讨论
- 关于java.util.Vector 或 java.util.Hashtable类过时的讨论
- 多线程Vector
- LinkedList,ArrayList,Vector,HashTable,HashMap
- LinkedList,ArrayList,Vector,HashTable,HashMap
- Vector与Hashtable 的用法
- Vector、ArrayList和hashtable hashmap
- HashTable、HashMap、Vector、ArrayList区别
- 网络字节序与主机字节序 和它们之间的相互转换函数
- cocos2dx lua 学习小坑整理
- hdu 5512 Pagodas(水题)
- hiho 5 数字三角形
- Spring MVC中拦截器小结
- 多线程使用Vector或HashTable
- android 锁屏程序开发
- 算法:C实现 数组
- SpringMVC拦截器(资源和权限管理)
- linux正则表达式-1
- Struts2拦截器介绍及说明
- hihoCoder挑战赛16 王胖浩与三角形
- Android NDK开发(二)——JNI访问和引用JAVA对象
- iOS把图片缓存到本地的几种方法