Java多线程编程核心技术代码记录
多线程
对象的组合
4.1 设计线程安全的类
001.p46-在设计线程安全类的过程中的三个基本要素?
4.1.2 依赖状态的操作
002.p46-实现某个等待先验条件为真时才执行的操作,可以通过什么方法?
003.p43-发布一个静态构造对象的最简单,最安全的方式是?为什么?
4.2 实例封闭
004.p49-写一个封闭+加锁实现一个类线程安全的DEMO?
@ThreadSafe
public class PersonSet {
private final Set myset = new HashSet();
public synchronized void addPerson(Person p) {
myset.add(p);
}
public synchronized boolean containsPerson(Person p) {
return myset.contains(p);
}
}
004.p50-实例封闭是构建线程安全类的最简单方式。
005.p50-Java平台的类库中提供了包装器工厂方法(如:Collections.synchronizedList及其类似方法),使得非线程安全的类可以在多线 程环境中安全的使用。这些工厂方法通过“装饰器模式”的原理是?什么是装饰器模式,原理,demo?
4.2.1 Java监视器模式
006.p51-什么是Java的监视器模式?Demo?举例Java(如线程安全计数器Counter、Vector、Hashtable)
Counter:
public class Counter {
private long value = 0;
public synchronized long getValue(){
return value;
}
public synchronized long increment(){
if(value==Long.MAX_VALUE)
throw new IllegalStateException("counter overflow");
return ++value;
}
Vector:
public class Vector extends AbstractList implements List, RandomAccess, Cloneable, java.io.Serializable {
protected Object[] elementData;
protected int elementCount;
public synchronized void copyInto(Object[] anArray) {
System.arraycopy(elementData, 0, anArray, 0, elementCount);
}
}
007.p51-通过一个私有锁来保护状态?demo?
public class PrivateLock{
private final Object mylock = new Object();
@GuardedBy("myLock")
Widget widget;
void someMethod(){
synchronized(mylock){
.....访问修改widget状态
}
}
}
008.p52-基于监视器模式的车辆追踪器demo?此模式的适应场景,优缺点,举例说明?
@ThreadSafe
public class MonitorVehicleTracker {
@GuardedBy("this")
private final Map locations;
public MonitorVehicleTracker(Map points) {
locations = deepCopy(points);
}
public synchronized Map getLocations() {
return deepCopy(locations);
}
public synchronized MutablePoint getLocation(String key) {
MutablePoint point = locations.get(key);
return point == null ? null : new MutablePoint(point);
}
public synchronized void setLocation(String id, int x, int y) {
if (id == null) {
return;
}
MutablePoint point = locations.get(id);
if (point == null) {
throw new IllegalArgumentException("No such ID: " + id);
}
point.setPoint(x, y);
}
private Map deepCopy(Map points) {
if (points == null) {
return Maps.newHashMap();
}
Map result = Maps.newHashMapWithExpectedSize(points.size());
for (String key : points.keySet()) {
result.put(key, new MutablePoint(points.get(key)));
}
return Collections.unmodifiableMap(result);
}
}
@NotThreadSafe
public class MutablePoint {
private int x, y;
public MutablePoint(int x, int y) {
this.x = x;
this.y = y;
}
public MutablePoint() {}
public MutablePoint(MutablePoint point) {
if (point == null) {
throw new IllegalArgumentException("param is null");
}
int[] pointArray = point.getPointArray();
x = pointArray[0];
y = pointArray[1];
}
}
public int[] getPointArray() {
int[] ret = new int[2];
ret[0] = x;
ret[1] = y;
return ret;
}
public void setPoint(int x, int y) {
this.x = x;
this.y = y;
}
}
适应场景:适合一致性的需求,获取一致的快照
不适合实时获取每辆车的最新信息,因为需要频繁的刷新快照。
4.3 线程安全性的委托
009.p54-基于委托的车辆追踪器?DEMO?
交由ConcurrentHashMap处理
@Immutable
public class Point {
public final int x,y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
}
@ThreadSafe
public class DelegatingVehicleTracker {
private final ConcurrentHashMap localtions;
private final Map unmodifiableMap;
public DelegatingVehicleTracker(Map points){
locations = new ConcurrentHashMap(points);
unmodifiableMap = Collections.unmodifiableMap(locations);
}
// 返回实时位置
public Map getLocations() {
return unmodifiableMap;
}
public Point getLocation(String id) {
return locations.get(id);
}
// 返回静态拷贝数据,而非实时数据
public Point getLocations_static(){
return Collections.unmodifiableMap(new HashMap(locations));
}
public void setLocation(String id, int x, int y) {
if (locations.replace(id,new Point(x, y)) == null)
throw new IllegalArgumentException("invalid vehicle name: " + id);
}
}
010.什么是CopyOnWrite容器?说说CopyOnWriteArrayList的实现原理? CopyOnWrite的应用场景?CopyOnWrite的缺点?
传送门
4.3.2 独立的状态变量
011.p56-将线程安全性委托给多个状态变量——图形组件,允许客户程序注册监控鼠标和键盘等事件的监听器?DEMO?
public class VisualComponent {
private final List keyListeners = new CopyOnWriteArrayList();
private final List monseListeners = new CopyOnWriteArrayList();
public void addKeyListener(KeyListener listener) {
keyListeners.add(listener);
}
public void addMonseListener(MonseListener monseListener){
monseListeners.add(monseListener);
}
public void removeKeyListener(KeyListener keyListener) {
keyListeners.remove(keyListener);
}
public void removeMonseListener(MonseListener monseListener) {
monseListeners.remove(monseListener);
}
}
012.p58-发布状态的车辆追踪器?DEMO?
// 线程安全且可变的Point类
@ThreadSafe
public class SafePoint {
@GuardedBy("this") private int x,y;
public SafePoint(int x, int y) {
this.x = x;
this.y = y;
}
private SafePoint (int[] a) { this(a[0], a[1]); }
private SafePoint (SafePoint p) { this(p.get()); }
public synchronized int[] get() { return new int[] { x, y }; }
public synchronized void set (int x, int y) {
this.x = x;
this.y = y;
}
}
// 安全发布底层状态的车辆追踪器
@ThreadSafe
public class PublishingVehicleTracker {
private final Map locations;
private final Map unModifiableMap;
public PublishingVehicleTracker (Map locations) {
locations = new ConcurrentHashMap(locations);
unModifiableMap = Collections.unModifiableMap(this.locations);
}
public Map getLocations() {
return unModifiableMap;
}
public SafePoint getLocation(String id) {
return locations.get(id);
}
public void setLocation(String id, int x, int y) {
if(!locations.containsKey(id))
throw new IllegalArgumentException("invalid vehicle name: " + id);
locations.get(id).set(x, y);
}
}
4.4 在现有的安全线程中添加功能
013.p60-在现有的安全线程中添加功能有几种方法?(添加一个新的原子操作)DEMO?
// 通过组合实现“若没有则添加”
@ThreadSafe
public class ImprovedList implements List {
private final List list;
public ImprovedList (List list) {
this.list = list;
}
public synchronized boolean putIfAbsent(T x) {
boolean absent = !list.contains(x);
if(absent)
list.add(x);
return !absent;
}
public synchronized void clear () { list.clear(); }
}
欢迎加入Java猿社区