JDK1.2引入最有争议性的改变是将集合类默觉得不是Thread安全性的。

一、Collection Class的概述

1. 具有Threadsafe 的Collection Class:
java.util.Vector(List) 列表集合,通过索引操作。
java.util.Stack(List) 继承自Vector,提供LIFO的顺序操作push进入,pop出元素。
java.util.Hashtable(Map) 一个简单、无序的key与value的映射。
java.util.concurrent.ConcurrentHashMap 一个实现无序的map的类,比Hashtable使用更少的同步机制。
java.util.concurrent.CopyOnWriteArrayList  提供无同步的Iterator。
java.util.concurrent.ConcurrentLinkedQueue 无限的FIFO队列。
2. Thread-Notification Collection Class
java.util.concurrent包下的线程安全的Queue:
ArrayBlockingQueue:有限的FIFO队列。
LinkedBlockingQueue:能够有限或无限的FIFO 队列。
SynchronousQueue:有限的FIFO队列。一种堵塞队列,当中每一个插入操作必须等待还有一个线程的相应移除操作 ,反之亦然。
PriorityBlockingQueue:一个无界堵塞队列,它使用与类 PriorityQueue 同样的顺序规则,而且提供了堵塞获取操作。
DelayQueue:Delayed 元素的一个无界堵塞队列,仅仅有在延迟期满时才干从中提取元素。

二、同步与Collection Class

使用Vector确保线程安全性样例:
import java.util.*;public class CharacterEventHandler {private Vector listeners = new Vector();public void addCharacterListener(CharacterListener cl) {listeners.add(cl);}public void removeCharacterListener(CharacterListener cl) {listeners.remove(cl);}public void fireNewCharacter(CharacterSource source, int c) {CharacterEvent ce = new CharacterEvent(source, c);CharacterListener[] cl = (CharacterListener[] )listeners.toArray(new CharacterListener[0]);for (int i = 0; i < cl.length; i++)cl[i].newCharacter(ce);}
}

使用非线程安全的ArrayList,使用synchronized method来确保线程安全的样例:
import java.util.*;public class CharacterEventHandler {private ArrayList listeners = new ArrayList();public synchronized void addCharacterListener(CharacterListener cl) {listeners.add(cl);}public synchronized void removeCharacterListener(CharacterListener cl) {listeners.remove(cl);}public synchronized void fireNewCharacter(CharacterSource source, int c) {CharacterEvent ce = new CharacterEvent(source, c);CharacterListener[] cl = (CharacterListener[] )listeners.toArray(new CharacterListener[0]);for (int i = 0; i < cl.length; i++)cl[i].newCharacter(ce);}
}

使用非线程安全的ArrayList,使用synchronized 块来确保线程安全的样例:
import java.util.*;public class CharacterEventHandler {private ArrayList listeners = new ArrayList();public void addCharacterListener(CharacterListener cl) {synchronized(listeners) {listeners.add(cl);}}public void removeCharacterListener(CharacterListener cl) {synchronized(listeners) {listeners.remove(cl);}}public void fireNewCharacter(CharacterSource source, int c) {CharacterEvent ce = new CharacterEvent(source, c);CharacterListener[] cl;synchronized(listeners) {cl = (CharacterListener[] )listeners.toArray(new CharacterListener[0]);}for (int i = 0; i < cl.length; i++)cl[i].newCharacter(ce);}
}

复杂的同步
使用线程安全的集合类,就不会出现不论什么的线程安全问题,比如:竞态条件吗?
答案是否定的,依旧会出现故障,当一个方法中涉及两次对同一个集合进行多次操作时就可能出现异常。
import java.util.*;
import javax.swing.*;
import javax.swing.table.*;public class CharCounter {public HashMap correctChars = new HashMap();public HashMap incorrectChars = new HashMap();private AbstractTableModel atm;public void correctChar(int c) {synchronized(correctChars) {Integer key = new Integer(c);Integer num = (Integer) correctChars.get(key);if (num == null)correctChars.put(key, new Integer(1));else correctChars.put(key, new Integer(num.intValue() + 1));if (atm != null)atm.fireTableDataChanged();}}public int getCorrectNum(int c) {synchronized(correctChars) {Integer key = new Integer(c);Integer num = (Integer) correctChars.get(key);if (num == null)return 0;return num.intValue();}}public void incorrectChar(int c) {synchronized(incorrectChars) {Integer key = new Integer(c);Integer num = (Integer) incorrectChars.get(key);if (num == null)incorrectChars.put(key, new Integer(-1));else incorrectChars.put(key, new Integer(num.intValue() - 1));if (atm != null)atm.fireTableDataChanged();}}public int getIncorrectNum(int c) {synchronized(incorrectChars) {Integer key = new Integer(c);Integer num = (Integer) incorrectChars.get(key);if (num == null)return 0;return num.intValue();}}public void addModel(AbstractTableModel atm) {this.atm = atm;}
}

三、生产者/消费者模式

以分割不同组的Thread的请求来进行异步处理数据。生产者是产生须要被处理的请求的Thread。消费者是接受奈尔请求并予以对应的Thread。这样的模式提供了一种清楚的分类让Thread能有更好的设计且可以更easy地调试。
仅仅需提供安全的方法从生产者传递数据给消费者,数据仅仅须要在生产者与消费者之间传递的非常短时间中确保线程安全性就可以。
能够使用线程安全的集合类:vector、list、queue。
生产者:
import java.util.*;
import java.util.concurrent.*;public class FibonacciProducer implements Runnable {private Thread thr;private BlockingQueue<Integer> queue;public FibonacciProducer(BlockingQueue<Integer> q) {queue = q;thr = new Thread(this);thr.start();}public void run() {try {for(int x=0;;x++) {Thread.sleep(1000);queue.put(new Integer(x));System.out.println("Produced request " + x);}} catch (InterruptedException ex) {}}
}

消费者:
import java.util.concurrent.*;public class FibonacciConsumer implements Runnable {private Fibonacci fib = new Fibonacci();private Thread thr;private BlockingQueue<Integer> queue;public FibonacciConsumer(BlockingQueue<Integer> q) {queue = q;thr = new Thread(this);thr.start();}public void run() {int request, result;try {while (true) {request = queue.take().intValue();result = fib.calculateWithCache(request);System.out.println("Calculated result of " + result + " from " + request);}} catch (InterruptedException ex) {}}
}

生产者与消费者是去耦的,生产者绝不会直接调用消费者。

四、使用Collection Class

使用哪个集合类最好呢?
使用没有同步化的集合类会有小小的性能提升。
对很多有竞争的算法,考虑改用并发的Collection
生产者/消费者考虑使用Queue替代集合类。
尽量降低同步的使用

Java 线程第三版 第八章 Thread与Collection Class 读书笔记相关推荐

  1. Java 线程第三版 第四章 Thread Notification 读书笔记

    一.等待与通知 public final void wait() throws InterruptedException 等待条件的发生. public final void wait(long ti ...

  2. Effective Java(第三版) 学习笔记 - 第四章 类和接口 Rule20~Rule25

    Effective Java(第三版) 学习笔记 - 第四章 类和接口 Rule20~Rule25 目录 Rule20 接口优于抽象类 Rule21 为后代设计接口 Rule22 接口只用于定义类型 ...

  3. 算法-排序-k排序(算法导论第三版第八章思考题8-5)

    算法-排序-k排序 算法导论第三版第八章思考题8-5 时间复杂度Θ(nlg(n/k)). 利用最小堆完成,把元素分成k个堆,每个堆大小⌈n/k⌉. 利用堆作为子排序稳定,也可以采用其他排序作为子排序, ...

  4. 算法导论水壶问题(第三版第八章思考题8-4)

    算法导论水壶问题 (第三版第八章思考题8-4) 本算法只适用于解题,不通用. 期望的时间复杂度O(nlgn) Kettle.h文件 #ifndef C11LEARN_KETTLE_H #define ...

  5. java虚拟机第三版学习

    java 编译执行流程 Java 源文件->编译器->字节码文件->JVM->机器码 Java 内存区域与内存溢出异常 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存 ...

  6. 浅析Java线程的三种实现

    一.前言 java.lang.Thread类是java的线程类.当生成一个Thread类的对象后,一个新的线程就产生了.Java中每一个线程都是通过某个特定的Thread对象的方法run()来完成其操 ...

  7. 计算机图形学(第四版)-第一个画线例子- 读书笔记P30

    说明:内容为计算机图形学(第四版)这本书的读书笔记,会记录这本书的一些编码知识和其他内容,目标:将厚书读薄yeah~ 1.OpenGL基本语法: 2.附加库: 3.OpenGL的安装和环境配置: 参考 ...

  8. 【Books系列】之第三本书:《新物种爆炸》读书笔记

    DATE: 2019.6.29 前言     2019年初,立下了2019年的奋斗目标和方向.第二条:读好书,读完6本书,做好读书笔记.前两本书读了感情励志类的故事和小说,第三本读了下面的这本书,读的 ...

  9. Java 螺纹第三版 第三章数据同步 读书笔记

    多线程间共享数据问题 一.Synchronizedkeyword atomic一词与"原子"无关,它以前被觉得是物质的最小的单元,不能再被拆解成更小的部分. 当一个方法被声明成sy ...

  10. JAVA | 线程(三)线程同步(重要)

    一.线程安全问题(银行取钱) 问题描述: 当两个人同时对一个账户进行操作取钱的时候,可能会出现线程安全问题 //定义一个用户类 public class Account {// 银行账户private ...

最新文章

  1. 安装Macports遇到的问题和PATH设置
  2. 市场营销部门OKR案例
  3. ProgressBar(圆形、水平进度条)的基本使用(点击Button1按钮,显示或消失圆形ProgressBar)(每点击一次Button2按钮,水平进度条增加10%)
  4. 第 4 章  超链接和路径
  5. Python 字符串和列表的转化 ,简单到尖叫
  6. java 泛型 泛型擦除(type erasure)
  7. java c 转换_java和c通信相关的数据类型转换
  8. Nordic Collegiate Programming Contest 2016
  9. Gulp vs Grunt 前端工程构建工具
  10. 【玩转win7之简单几步为闪存盘加密】
  11. redis如何选择合适的数据结构
  12. 你敢信?用数学公式编辑器也能打出化学公式
  13. python千位分隔符_31 python中format方法:字段宽度、精度和千位分隔符 符号、对齐和用0填充...
  14. Flutter自定义主题颜色
  15. CSS特效七:Hover下拉菜单
  16. 产业的互联网化是什么时代_新时代:为什么互联网公司不应忽视65岁以上的一代...
  17. java计算机毕业设计的小区物业管理系统源程序+mysql+系统+lw文档+远程调试java计算机毕业设计的小区物业管理系统源程序+mysql+系统+lw文档+
  18. JAVA 利用ASCII码偏移(来自IDEA免费激活码游戏)
  19. 1.机器人导航关键技术研究
  20. Java学习笔记(二十三)日志体系(logback)

热门文章

  1. HTML DOM Event(事件)
  2. 《WF编程》系列之4 - 漫游工作流:Widows Workflow Runtime及其服务
  3. 69期-Java SE-004_循环、数组-001-002
  4. Vue2 后台管理系统解决方案
  5. Hibernate ——二级缓存
  6. 【转】android开发 dts、各种接口porting----不错
  7. Eclipse设置护眼背景
  8. Emacs正则表达式+零宽断言/环视
  9. Linux测试磁盘能力
  10. ping IP简单应用,查找故障