1、使用ThreadLocal为线程设置私有变量
public class ThreadLocal_test {
// private String content;
ThreadLocal<String> t1 = new ThreadLocal<>();
ThreadLocal<String> t2 = new ThreadLocal<>();
public String getContent() {
String s = t1.get();
return s;
}
public void setContent(String content) {
//变量绑定到当前线程
t1.set(content);
}
public String getContent2() {
String s = t2.get();
return s;
}
public void setContent2(String content) {
//变量绑定到当前线程
t2.set(content);
}
public static void main(String[] args) {
ThreadLocal_test demo = new ThreadLocal_test();
for (int i = 0; i < 20; i++) {
Thread thread = new Thread(() -> {
/*
每个线程:存一个变量,过一会 取出这个变量
*/
demo.setContent(Thread.currentThread().getName() + "的数据");
demo.setContent2(Thread.currentThread().getName() + "的数据2");
System.out.println("----------------------------------------");
System.out.println(Thread.currentThread().getName() + "---->" + demo.getContent());
System.out.println(Thread.currentThread().getName() + "--2-->" + demo.getContent2());
});
thread.setName("线程" + i);
thread.start();
}
}
}
上述代码中,每个线程分别给ThreadLocal类型的变量设置值,当前线程设置的值是什么,自己拿出的值也是什么,任何一个线程不能拿到其余线程设置的值。
2、使用构造方法,将需要私有化的数据传入,只有当前线程可以访问到,其他线程无法访问
public class ThreadClass implements Runnable{
String ele;
ThreadClass(String ele){
this.ele = ele;
}
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName() + "=>" + this.getEle());
}
System.out.println("--------------------------------------------------");
public String getEle() {
return ele;
}
}
public static void main(String[] args) {
ExecutorService pool = Executors.newFixedThreadPool(20);
for (int i = 0; i < 20; i++) {
//通过构造方法将数据传入,使其成为当前线程私有的,其他类无法访问到
ThreadClass temp = new ThreadClass("传入的数据为" + (i + 1));
pool.execute(temp);
}
}
上述代码,在各自run方法中多次输出ele,观察输出的ele是否和自己构造方法中传入的数据相同。
由于使用了线程池,线程池中的名字是预定义好的,而且特意将线程池的大小设置为20,便于比较当前拿到的值是否和自己设置的值相等。所以在run方法中,多次获取当前线程实例的ele值,验证构造方法传入的值和线程对象拿到的值。
两种方法的区别:
使用ThreadLocal,直观上是只有一个ThreadLocal变量供所有的线程使用,但是各个线程set和get到的值具有一致性(哪个线程设置的值是什么,该线程拿到的值就是什么,不会拿到其他线程设置的值)
使用构造方法,可以将每个Runnable的实现类,或者Thread的子类,看作普通类,实例化的时候传进去的数据不同,每个线程就是不同的实例化对象,每个对象只能拿到自己变量,不能拿到其他对象的。