一。为什么需要多线程
1. 与用户的更好交互(Better Interaction with the User),减少响应等待
2. 模拟同时进行的活动(Simulation of Simultaneous Activities)
3. 开发利用多处理器(Exploitation of Multiple Processors)
4. 简化对象建模(Simplify Object Modeling)
5. 当等待慢的I/O操作时,可以做其他事情(Do Other Things While Waiting for Slow IO Operations)
二。什么是线程安全(摘自百度百科)
如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的。
或者说:一个类或者程序所提供的接口对于线程来说是原子操作或者多个线程之间的切换不会导致该接口的执行结果存在二义性,也就是说我们不用考虑同步的问题。
线程安全问题都是由全局变量及静态变量引起的。
若每个线程中对全局变量、静态变量只有读操作,而无写操作,一般来说,这个全局变量是线程安全的;若有多个线程同时执行写操作,一般都需要考虑线程同步,否则就可能影响线程安全。
三。如何保证线程安全
1. 使用synchronized关键字
/**
* 以this为锁的同步代码
*/
public synchronized void testSyn(){
System.out.println("testSyn");
}
/**
* 对这个类的所有对象都用同一个锁
*/
public static synchronized void testSyn2(){
System.out.println("testSyn2");
}
/**
* 对这个类的所有对象都用同一个锁。
*/
public void testSyn3(){
synchronized(TestRunner.class){
System.out.println("testSyn2");
}
}
2. volatile
volatile 修饰的成员变量在每次被线程访问时,都强迫从共享内存中重读该成员变量的值。而且,当成员变量发生变化时,强迫线程将变化值回写到共享内存。
优势:这样在任何时刻,两个不同的线程总是看到某个成员变量的同一个值。
3. ThreadLocal
ThreadLocal 保证不同线程拥有不同实例,相同线程一定拥有相同的实例,即为每一个使用该变量的线程提供一个该变量值的副本,每一个线程都可以独立改变自己的副本,而不是与其它线程的副本冲突。
优势:提供了线程安全的共享对象
与其它同步机制的区别:同步机制是为了同步多个线程对相同资源的并发访问,是为了多个线程之间进行通信;而 ThreadLocal 是隔离多个线程的数据共享,从根本上就不在多个线程之间共享资源,这样当然不需要多个线程进行同步了。