两个例子来说明:
1)线程不安全的示例:
public class TestMain {
@Test
public void main() {
int a = 0;
ThreadNotSafe rt = new ThreadNotSafe(a);
Thread thread1 = new Thread(rt);
thread1.start();
Thread thread2 = new Thread(rt);
thread2.start();
Thread thread3 = new Thread(rt);
thread3.start();
}
}
public class ThreadNotSafe implements Runnable{
int a;
public ThreadNotSafe(int a){
this.a = a;
}
public void run() {
for(int i=0;i<5;i++){
System.out.println(Thread.currentThread().getName() +": " + a++);
}
}
}
运行结果:
Thread-0: 0
Thread-0: 2
Thread-0: 3
Thread-0: 4
Thread-0: 5
Thread-1: 1
Thread-1: 6
Thread-1: 8
Thread-1: 9
Thread-1: 10
Thread-2: 7
Thread-2: 11
Thread-2: 12
Thread-2: 13
Thread-2: 14
2)ThreadLocal线程安全的示例:
public class TestMain {
@Test
public void threadSafe(){
ThreadLocal<Integer> aTL = new ThreadLocal<Integer>(){
public Integer initialValue(){
return 0;
}
};
RunnableThread rt = new RunnableThread(aTL);
Thread thread1 = new Thread(rt);
thread1.start();
Thread thread2 = new Thread(rt);
thread2.start();
Thread thread3 = new Thread(rt);
thread3.start();
}
}
public class ThreadSafe implements Runnable{
ThreadLocal<Integer> a;
public ThreadSafe(ThreadLocal<Integer> a){
this.a = a;
}
public void run() {
for(int i=0;i<5;i++){
try {
Thread.sleep(10L);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
this.a.set(this.a.get() + 1);
System.out.println(Thread.currentThread().getName() +": " + this.a.get());
}
}
}
运行结果:(不知为何这里只输出到3,不过不影响本文的主题)
Thread-0: 1
Thread-2: 1
Thread-1: 1
Thread-0: 2
Thread-2: 2
Thread-1: 2
Thread-0: 3
Thread-2: 3
Thread-1: 3
以上两个例子,三条线程都共用了一个实例。
结果一:每个线程对a值的操作都会影响到其它线程;
结果二:每个线程对a值的操作对其它线程都没有影响,每个线程输出的独立的序列,因为ThreadLocal对每条线程生成了一个单独的副本。