1 出现线程安全问题的条件
- 1)是否多线程环境
- 2)是否有共享数据
- 3)是否有多条语句操作共享数据
1)2)没法儿改,只能改3):把多条语句包成一个整体,让某个线程执行的时候其它线程不能进去执行 --> 同步机制。
2 同步(synchronized)
2.1 同步 代码块
- synchronized(对象){需要同步的代码}
- 注:同步可以解决安全问题的根本就在这个“对象”上,该对象如同锁的功能,可以是任意对象
- !!多个线程必须是同一把锁!!
- 弊:线程较多时,每个线程都要去判断锁,很耗费资源,降低程序运行效率
2.2 同步 方法
- 如:private synchronized void get(){}
- 锁的对象:this
- !!对象锁!!
2.3 同步 静态方法
- 如:private static synchronized void get(){}
- 锁的对象:类的字节码对象(RunnableMy.class)
- !!类锁!!
3 Lock
- 为了更清晰的表达如何加锁和释放锁,JDK5以后提供了一个新的锁对象Lock,他是一个接口
- 常用实现类:
ReentrantLock
- 方法:
void lock()
:获取锁(加锁)
void unlock()
:释放锁(开锁) - 格式:
try {
// 加锁
lock.lock();
//方法体
//...
} finally {
//不管try中的语句有没有出现问题,finally中的语句一定会执行,即释放锁的步骤一定能完成
// 释放锁
lock.unlock();
}
4 线程安全的类
StringBuffer sb = new StringBuffer();
Vector<String> v = new Vector<String>();
Hashtable<String,String> h = new Hashtable<String,String>();
Vector
即使在要求线程安全的条件下也基本不用,- 这时我们一般用下面的方式来得到线程安全的集合:
List<String> list1 = Collections.synchronizedList(new ArrayList<String>());
注:推荐同步方法,不推荐同步代码块