synchronized和ThreadLocal都是应用于线程共享变量时的方法,但它们对应的应用场景不同。我们可以这样理解,多个线程共享同一个对象的变量,当多个线程需要维护的是同一个变量值时(即同一个时刻该变量一定只有唯一值是正确的),则用synchronized进行同步;然而当多个线程需要维护的不是同一个变量值时,它们只需要获取该变量的初始值,该变量在每个线程中的值都是独立的、无关的,则用ThreadLocal修饰变量,为每个线程创建一份变量的副本。
ThreadLocal类的方法如下:
//应覆盖此方法以提供初始值
protected initialValue()
//得到本线程的当前值
T get()
//为本线程设置一个新值
void set(T t)
//删除本线程的对应值
void remove()
代码实例:
编写BasicClass类,包含一个整数变量,初始值为10。两个线程共享同一个BasicClass对象中的整数变量,线程一直接输出变量值,线程二将变量乘10后再输出,要求两个进程中的该变量相互独立、无关,则正确情况下线程一应输出10,线程二应输出100。
情况一:不使用ThreadLocal
1.BasicClass
package ThreadLocal;
public class BasicClass {
Integer a = new Integer(10);
}
2.Thread1
package ThreadLocal;
public class Thread1 extends Thread {
private BasicClass b;
public Thread1(BasicClass b) {
this.b = b;
}
@Override
public void run() {
try {
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("1:"+b.a);
}
}
3.Thread2
package ThreadLocal;
public class Thread2 extends Thread {
private BasicClass b;
public Thread2(BasicClass b) {
this.b = b;
}
@Override
public void run() {
b.a = b.a * 10;
System.out.println("2:" + b.a);
}
}
4.MainClass
package ThreadLocal;
public class MainClass {
public static void main(String[] args) {
BasicClass b = new BasicClass();
Thread1 t1 = new Thread1(b);
Thread2 t2 = new Thread2(b);
t1.start();
t2.start();
}
}
5.输出
2:100
1:100
Process finished with exit code 0
情况二:使用ThreadLocal
1.BasicClass
package ThreadLocal;
public class BasicClass {
ThreadLocal<Integer> a = new ThreadLocal<Integer>(){
@Override
protected Integer initialValue() {
return new Integer(10);
}
};
}
2.Thread1
package ThreadLocal;
public class Thread1 extends Thread {
private BasicClass b;
public Thread1(BasicClass b) {
this.b = b;
}
@Override
public void run() {
try {
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("1:"+b.a.get());
}
}
3.Thread2
package ThreadLocal;
public class Thread2 extends Thread {
private BasicClass b;
public Thread2(BasicClass b) {
this.b = b;
}
@Override
public void run() {
b.a.set(new Integer(b.a.get()*10));
System.out.println("2:" + b.a.get());
}
}
4.MainClass
package ThreadLocal;
public class MainClass {
public static void main(String[] args) {
BasicClass b = new BasicClass();
Thread1 t1 = new Thread1(b);
Thread2 t2 = new Thread2(b);
t1.start();
t2.start();
}
}
5.输出
2:100
1:10
Process finished with exit code 0