先看下面问题:多个线程访问全局变量x,然后将x与i累加,启动10个线程,想让每个线程的输出结果都是一样的55,但是实际不是的。
注意:多个接口共享则全局变量为空
-
package ThreadTest;
-
-
public class Counter {
-
-
private int x = 0;
-
-
// 计数方法
-
public void count() {
-
for( int i= 0;i<= 10;i++) {
-
x = x+i;
-
}
-
System.out.println(Thread.currentThread().getName()+ "--"+x);
-
}
-
-
public static void main(String[] args) {
-
// 定义线程实现接口
-
Runnable runnable = new Runnable(){
-
Counter counter = new Counter();
-
-
public void run() {
-
counter.count();
-
}
-
};
-
// 启动10个线程
-
for( int i= 0;i< 10;i++) {
-
new Thread(runnable).start();
-
}
-
}
-
}
实际输出是无规则的。
解决方案一:
-
package ThreadTest;
-
-
public
class Counter {
-
-
ThreadLocal<Integer> th=
new ThreadLocal<Integer>(){
-
protected Integer initialValue() {
-
return
0;
-
}
-
};
-
// 计数方法
-
public void count() {
-
for(
int i=
0;i<=
10;i++) {
-
th.set(th.get()+i);
-
}
-
System.out.println(Thread.currentThread().getName()+
"--"+th.get());
-
}
-
-
}
用ThreadLocal,输出结果是55,ok!
由此可以证明,ThreadLocal为每一个线程保存每一个变量,而且每个线程拿到的都是自己的那一份。
解决方案二:
将全局变量局部化
-
public
class Count {
-
-
-
public void count() {
-
int x =
0;
-
for(
int i =
1; i <=
10; i++) {
-
x=x+i;
-
}
-
System.out.println(Thread.currentThread().getName() +
"-" + x);
-
}
-
}
每个线程都有一份自己的局部变量,因此不会产生线程问题。
解决方案三:对象局部化
-
public static void main(String[] args) {
-
Runnable runnable =
new Runnable() {
-
public void run() {
-
Count count =
new Count();
-
count.count();
-
}
-
};
-
for(
int i =
0; i <
10; i++) {
-
new Thread(runnable).start();
-
}
-
}
每个对象都会有一个自己的全局变量。不会产生线程问题。