深入理解ThreadLocal类+Demo详细解析

 

通俗的来讲,ThreadLocal主要作用就是让各自线程自能取得各自线程里面的东西,也即是各自线程只能忙活自己的事,管不了别人的事,通过下面的Demo来看一下ThreadLocal是否能实现这个功能

ThreadLocal类就像Map,List这种类一样也是用来存储数据的,只是ThreadLocal类主要是为了线程数据存储而生的,目的是保证每一个线程只能存储和取出自己的东西。另外这个类是带泛型的,你想使用ThreadLocal存什么数据类型就要在泛型里面是用什么泛型参数。

public class TestDemo{//这里为什么使用static关键字进行修饰,自己去想,不解释。private static ThreadLocal sThreadLocal=new ThreadLocal<>();public static void main(String args[]) {//主线程sThreadLocal.set("这是在主线程中");System.out.println("线程名字:"+Thread.currentThread().getName()+"---"+sThreadLocal.get());//线程anew Thread(new Runnable() {public void run() {sThreadLocal.set("这是在线程a中");System.out.println("线程名字:"+Thread.currentThread().getName()+"---"+sThreadLocal.get());}},"线程a").start();//线程bnew Thread(new Runnable() {public void run() {sThreadLocal.set("这是在线程b中");System.out.println("线程名字:"+Thread.currentThread().getName()+"---"+sThreadLocal.get());}},"线程b").start();//线程c  这个线程是使Lambda建立的,跟上面两个是一样的。不会使用Lambda表达式的同学请看我的另一篇博客new Thread(()->{sThreadLocal.set("这是在线程c中");System.out.println("线程名字:"+Thread.currentThread().getName()+"---"+sThreadLocal.get());},"线程c") .start();}
}

输出如下:
 

线程名字:main---这是在主线程中
线程名字:线程a---这是在线程a中
线程名字:线程b---这是在线程b中
线程名字:线程c---这是在线程c中

看完这个程序是不是很清楚了。我们开启了三个线程,加上主线程就是四个线程,每个线程都set了一句话,然后使用get取出,他们各自取出各自的设置内容,并没有取出别的线程的内容。

下面我们通过一个实例加深对ThreadLocal类的实际用,让我们看看真正开发之中是怎么使用ThreadLocal类的。

在讲解ThreadLocal类之前首先我们先来看一下如下程序:

class Message{private String note;public void setNote(String note) {this.note=note;}public String getNote() {return this.note;}
}
class MessageConsumer{public void print(Message msg) {System.out.println(Thread.currentThread().getName()+msg.getNote());}
}public class TestDemo{public static void main(String args[]) {new Thread(()->{Message msgA=new Message();msgA.setNote("中国矿业大学北京");new MessageConsumer().print(msgA);},"学生A") .start();new Thread(()->{Message msgB=new Message();msgB.setNote("清华大学");new MessageConsumer().print(msgB);},"学生B").start();}
}

以上程序输出为

学生B清华大学
学生A中国矿业大学北京

(注释:上面的程序使用了La'mbda表达式,不知道Lambda表达式的同学可以参考我的另一篇博客。Lambda表达式还是很重要的,希望大家能够能弄懂。)

当然,这个程序的输出是完全正确的。但是现在我有一个这样的需求:我不想把设置好数据的Message对象传给MessageConsumer的print()方法了,但是要求是还是能正常输出以上结果,那又怎么办?

我们的思路是:新建一个类里面有一个静态的Message对象,拿着这个对象进行操作就行了,现在我们就来看看代码的具体实现:

class Message{private String note;public void setNote(String note) {this.note=note;}public String getNote() {return this.note;}
}
class MessageConsumer{public void print() {System.out.println(Thread.currentThread().getName()+MyUtil.msg.getNote());}
}class MyUtil{public static Message msg;
}public class TestDemo{public static void main(String args[]) {new Thread(()->{Message msgA=new Message();msgA.setNote("中国矿业大学北京");MyUtil.msg=msgA;new MessageConsumer().print();},"学生A") .start();new Thread(()->{Message msgB=new Message();msgB.setNote("清华大学");MyUtil.msg=msgB;new MessageConsumer().print();},"学生B").start();}
}

以上程序的输出:

public class ThreadLocal extends Object{}下面是ThreadLocal类主要的方法:public void set(T value)//存一个数据public T get()//取一个数据

现在使用ThreadLocal来修改以上出现问题的代码,如下:

学生A中国矿业大学北京
学生B清华大学

完美解决,这就是ThreadLocal的主要用途。


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部