大多数类都是由其他类组合起来的。所以组合后的类是否是同步安全的有时候会让人很迷惑。
(1)设计线程安全的类
a) 确定对象状态由哪些变量构成
b) 确定限制状态变量的不变约束
c) 制定管理并发访问对象状态的策略.
(2)数据限制为private,访问对象的方法设置为同步的可以有效的确保线程安全,且不要将数据发布到其他非线程安全的类中.发布到期望可用的范围内.
(3)Java监视器模式保护对象,其实就是将对象数据私有化,set,get方法同步化.
(4)一般情况来说,一个由线程安全的组件(类)组成的类,就是线程安全的.
(5)一般来说检查再运行的方式,并且并未使用同步,那是不安全不可取的方式.即便是检查的对象是线程安全的.两个线程安全的对象在非线程安全的对象中检查-运行,是不安全的.
如果组合后,一个状态集(对象中的对象)需要发布到公共的域中,那么其他方法使用这个集中的方法一定要在这个集上加锁,避免两个线程使用集的锁非同一锁.如下:
class B{ public static List lis=Collections.synchronizedList(new ArrayList()); public synchronized void put(String s){ lis.add(s); }
}
你不知道其他线程是否会直接使用lis 即使看上去put方法是同步了,但是如果直接使用lis使用的是list的锁而put使用的是B对象的锁.可以改成
class B{ public static List lis=Collections.synchronizedList(new ArrayList()); public synchronized void put(String s){ synchronized(lis){ lis.add(s); } } }
如此就同步使用了list的锁;其实么.大家都会选择隐藏掉list,一般不会发布list这种做法一但发布list就必须使用第二种方式,