1、 * * author Brian Goetz and Tim Peierls */ ThreadSafe public final class Counter GuardedBy(this) 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
2、; 注:不理解对象的不可变约束和后验条件,就不能保证线程的安全性。要约束状态变量的有效值或者状态转换,就需要原子性与封装性。实例限制:限制性使构造线程安全的类更容易。因为类的状态被限制后,分析它的线程安全性时,就不必检查完整的程序。将数据封装在实体内部,把对数据的访问限制在对象的方法上,更易确保线程在访问数据时总能获得正确的锁。示例如下:import java.util.*; * PersonSet * Using confinement to ensure thread safety public class PersonSet ) private final Set mySet = new
3、 HashSet(); public synchronized void addPerson(Person p) mySet.add(p); public synchronized boolean containsPerson(Person p) return mySet.contains(p); interface Person HashSet是一个线程安全的类,通过公开的方法进行同步读写操作,确保了线程的安全性。Java监视器模式:像Vector和HashTable这样的核心库类,都是采用了Java监视器模式,其最大优势在于简单。Java监视器模式仅仅是一种习惯约定:任意锁对象只要始终如一
4、地使用,都可以用来保护对象的状态。来看个私有锁保护状态的示例: * PrivateLock * Guarding state with a private lock public class PrivateLock private final Object myLock = new Object();myLock) Widget widget; void someMethod() synchronized (myLock) / Access or modify the state of widget 实际上同步策略中Counter.java也是一个简单的Java监视器模式的示例。下面是一个基于
5、监视器的机动车追踪器: * MonitorVehicleTracker * Monitor-based vehicle tracker implementation public class MonitorVehicleTracker ) private final Map locations; public MonitorVehicleTracker(Map locations) this.locations = deepCopy(locations); public synchronized Map getLocations() return deepCopy(locations); pu
6、blic synchronized MutablePoint getLocation(String id) MutablePoint loc = locations.get(id); return loc = null ? null : new MutablePoint(loc); public synchronized void setLocation(String id, int x, int y) if (loc = null) throw new IllegalArgumentException(No such ID: + id); loc.x = x; loc.y = y; priv
7、ate static Map deepCopy(Map m) Map result = new HashMap for (String id : m.keySet() result.put(id, new MutablePoint(m.get(id); return Collections.unmodifiableMap(result); * MutablePoint * Mutable Point class similar to java.awt.Point NotThreadSafe public class MutablePoint public int x, y; public Mu
8、tablePoint() x = 0; y = 0; public MutablePoint(MutablePoint p) this.x = p.x; this.y = p.y;委托线程安全:委托线程安全,就是使用现有的线程安全的类来实现线程安全,即由其代为控制线程安全。下面来看个使用委托的机动车追踪器,ConcurrentMap线程安全委托:import java.util.concurrent.*;import java.awt.*;import java.awt.Point; * DelegatingVehicleTracker * Delegating thread safety t
9、o a ConcurrentHashMap public class DelegatingVehicleTracker private final ConcurrentMap private final Map unmodifiableMap; public DelegatingVehicleTracker(Map points) locations = new ConcurrentHashMap(points); unmodifiableMap = Collections.unmodifiableMap(locations); public Map getLocationsAsStatic(
10、) return Collections.unmodifiableMap( new HashMap(locations); * Point * Immutable Point class used by DelegatingVehicleTracker Immutable public class Point public final int x, y; public Point(int x, int y) this.x = x; this.y = y;Point是不可变对象,它是线程安全的。来看一下将线程安全委托到多个隐含变量:import java.awt.event.KeyListene
11、r;import java.awt.event.MouseListener; * VisualComponent * Delegating thread safety to multiple underlying state variables public class VisualComponent private final List keyListeners = new CopyOnWriteArrayList mouseListeners = new CopyOnWriteArrayList public PublishingVehicleTracker(Map this.locati
12、ons = new ConcurrentHashMap(locations); this.unmodifiableMap = Collections.unmodifiableMap(this.locations); public SafePoint getLocation(String id) if (!locations.containsKey(id) locations.get(id).set(x, y);扩展已有线程安全类:重要思想:缺少即加入。扩展Vector为例: * BetterVector * Extending Vector to have a put-if-absent me
13、thod public class BetterVector extends Vector / When extending a serializable class, you should redefine serialVersionUID static final g serialVersionUID = -3963416950630760754L; public synchronized boolean putIfAbsent(E x) boolean absent = !contains(x); if (absent) add(x); return absent;使用客户端加锁(缺少即加入):明确可变约束,加锁的位置很重要。 * ListHelder * Examples of thread-safe and non-thread-safe implementations of * put-if-absent helper methods for List class BadListHelper public List list = Collections.synchronizedList(new ArrayList();list.contains(x);
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1