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导论、 第二章Thread的创建与管理读书笔记

    第一章 Thread导论 为何要用Thread ? 非堵塞I/O      I/O多路技术      轮询(polling)      信号 警告(Alarm)和定时器(Timer) 独立的任务(Ta ...

  2. Java 螺纹第三版 第一章Thread介绍、 第二章Thread创建和管理学习笔记

    第一章 Thread导论 为何要用Thread ? 非堵塞I/O      I/O多路技术      轮询(polling)      信号 警告(Alarm)和定时器(Timer) 独立的任务(Ta ...

  3. Java 线程第三版 第九章 Thread调度 读书笔记

    一.Thread调度的概述 import java.util.*; import java.text.*; public class Task implements Runnable { long n ...

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

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

  5. Java 线程第三版 第五章 极简同步技巧 读书笔记

    一.能避免同步吗? 取得锁会由于下面原因导致成本非常高:     取得由竞争的锁须要在虚拟机的层面上执行很多其它的程序代码.     要取得有竞争锁的线程总是必须等到锁被释放后. 1. 寄存器的效应 ...

  6. 精通正则表达式(第三版)——Mastering Regular Expressions,3rd Edition——读书笔记1

    基础知识介绍: 子表达式匹配 环视 引号内的字符串:"(^")*" 12小时制:(1[0123]|[1-9]):[0-5][0-9]*(am|pm) 24小时制:(([0 ...

  7. 精通正则表达式(第三版)—Mastering Regular Expressions,3rd Edition—读书笔记2

    1.肯定断言:必须匹配一个字符 排除型字符组:匹配未列出字符的字符组 2.范围表示法——列出范围内所有的字符 大多数情况下,不会影响执行速度.但是,某些实现方式不能完全优化字符组.所以,最好是有范围表 ...

  8. 0038 Java学习笔记-多线程-传统线程间通信、Condition、阻塞队列、《疯狂Java讲义 第三版》进程间通信示例代码存在的一个问题

    调用同步锁的wait().notify().notifyAll()进行线程通信 看这个经典的存取款问题,要求两个线程存款,两个线程取款,账户里有余额的时候只能取款,没余额的时候只能存款,存取款金额相同 ...

  9. 疯狂java讲义 第三版 笔记

      java7新加特性: 0B010101  二进制数 int c=0B0111_1111;   数值中使用下划线分隔 switch 支持String类型   字符串常量放在常量池 String s0 ...

随机推荐

  1. pyqt动态创建一系列组件并绑定信号和槽(网友提供学习)

    # -*- coding: utf-8 -*- # python:2.x __author__ = 'Administrator' #如上图要求:创建指定多个复选框,一种是通过QT设计器Designe ...

  2. [转]Binarized Neural Networks_ Training Neural Networks with Weights and Activations Constrained to +1 or −1

    原文: 二值神经网络(Binary Neural Network,BNN) 在我刚刚过去的研究生毕设中,我在ImageNet数据集上验证了图像特征二值化后仍然具有很强的表达能力,可以在检索中达到较好的 ...

  3. [Ext JS 4] 实战之Grid, Tree Gird编辑Cell

    前言 本篇这里以稍微复杂一点的Tree Grid 来介绍. 在写编辑grid 之, 先来看一下 grid 的 selType 的配置. 先给一个简单的Tree grid 的例子: Ext.onRead ...

  4. LabVIEW新手5大错误

    虽然NI LabVIEW软件长期以来一直帮助工程师和科学家们快速开发功能测量和控制应用,但不是所有的新用户都会遵循LabVIEW编程的最佳方法. LabVIEW图形化编程比较独特,因为只需看一眼用户的 ...

  5. hdu 2612 Find a way(BFS)

    题目链接:hdu2612 思路:题意是求两个人到某一个KFC花费时间和最小,其实就是求最短距离和,用两个BFS,分别以两个人为起点,分别记录下两人到每个KFC的距离,然后求出最小的和 #include ...

  6. java编程中的Java.Lang.Math类

    1. Math.PI  :表示的是圆周率常量: 2.Math.E    :表示的是普通常量(e): 3.abs()方法: 表示取绝对值 eg1: int x = Math.abs(50L);     ...

  7. 使用 ETag 和 Last-Modified 报头减轻服务器压力(转)

    介绍你的网站在并发访问很大并且无法承受压力的情况下,你会选择如何优化?很多人首先会想从服务器缓存方面着手 对程序进行优化,许多不同的服务器缓存方式都有他们自己的特点,像我曾经参与的一些项目中,根据缓存 ...

  8. 关于降低android手机摄像头预览分辨率

    假设现在有这样一个需求需要一直开着手机摄像头 但是不做任何拍照动作 但是每个手机的相机分辨率都不同 而默认预览的时候参数是最大分辨率 这样有时候就回导致电量损耗的加快 所以我们可以采取降低相机分辨率的 ...

  9. html布局

    1.div <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8 ...

  10. (原)ubuntu16中安装moses

    转载请注明出处: http://www.cnblogs.com/darkknightzh/p/5653186.html 在ubuntu14中,可以使用下面的语句安装moses: luarocks in ...