java线程类应用,【Java多线程与并发库】6.ThreadLocal类及应用技巧

之前我们了解了实现线程范围内数据共享的机制,接下来我们

可以使用JDK5提供的ThreadLocal类,来实现线程范围内数据共享。

ThreadLocal类其实就类似于我们上一次创建的Map。

我们创建一个测试类,来使用ThreadLocal类实现线程范围内数据共享:

我们的类A和类B每次都从线程中获取data值打印,为了保证每次打印的数据是该线程的数据,

类A和类B的数据都从ThreadLocal中获取。

package cn.edu.hpu.test;

import java.util.Random;

public class ThreadTest7 {

private static Random dandom=new Random();

private static ThreadLocal x=new ThreadLocal();

public static void main(String[] args) {

for(int i=0;i<2;i++){

new Thread(new Runnable(){

public void run() {

int data=dandom.nextInt();

System.out.println(Thread.currentThread().getName()

+"放入数据:"+data);

x.set(data);

new A().get();

new B().get();

}

}).start();

}

}

static class A{

public void get(){

System.out.println("A 从"+Thread.currentThread().getName()

+"中取的数据:"+x.get());

}

}

static class B{

public void get(){

System.out.println("B 从"+Thread.currentThread().getName()

+"中取的数据:"+x.get());

}

}

}

结果:

0818b9ca8b590ca3270a3433284dd417.png

实现了每个线程中的数据共享在每个线程自己的范围内。线程之间的数据不会混杂在一起。

如果有N个变量需要做到线程范围内数据共享,应该如何做到?

一个ThreadLocal只能放一个变量,我们可以使用多个ThreadLocal来实现,

如果共享的数据量过大,我们就把这些数据放在一个对象中,然后在ThreadLocal中

存储这一个对象。

package cn.edu.hpu.test;

import java.util.Random;

public class ThreadTest7 {

private static Random dandom=new Random();

private static ThreadLocal MyThreadScopeData=new ThreadLocal();

public static void main(String[] args) {

for(int i=0;i<2;i++){

new Thread(new Runnable(){

public void run() {

int data=dandom.nextInt();

System.out.println(Thread.currentThread().getName()

+"放入数据:"+data);

MyThreadScopeData ScopeData=new MyThreadScopeData();

ScopeData.setName("name"+data);

ScopeData.setAge(data);

MyThreadScopeData.set(ScopeData);

new A().get();

new B().get();

}

}).start();

}

}

static class A{

public void get(){

System.out.println("A 从"+Thread.currentThread().getName()

+"中取的数据:"+MyThreadScopeData.get().getName()

+MyThreadScopeData.get().getAge());

}

}

static class B{

public void get(){

System.out.println("A 从"+Thread.currentThread().getName()

+"中取的数据:"+MyThreadScopeData.get().getName()

+MyThreadScopeData.get().getAge());

}

}

}

class MyThreadScopeData{

private String name;

private int age;

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public int getAge() {

return age;

}

public void setAge(int age) {

this.age = age;

}

}

结果:

0818b9ca8b590ca3270a3433284dd417.png

这样就可以在线程范围内共享N中数据了。

上面的设计其实不够好,但是要设计更加优雅一点,不要看到我们使用ThreadLocal的痕迹:

package cn.edu.hpu.test;

import java.util.Random;

public class ThreadTest7 {

private static Random dandom=new Random();

public static void main(String[] args) {

for(int i=0;i<2;i++){

new Thread(new Runnable(){

public void run() {

int data=dandom.nextInt();

System.out.println(Thread.currentThread().getName()

+"放入数据:"+data);

MyThreadScopeData.getThreadInstance().setName("name"+data);

MyThreadScopeData.getThreadInstance().setAge(data);

new A().get();

new B().get();

}

}).start();

}

}

static class A{

public void get(){

System.out.println("A 从"+Thread.currentThread().getName()

+"中取的数据:"+MyThreadScopeData.getThreadInstance().getName()

+MyThreadScopeData.getThreadInstance().getAge());

}

}

static class B{

public void get(){

System.out.println("A 从"+Thread.currentThread().getName()

+"中取的数据:"+MyThreadScopeData.getThreadInstance().getName()

+MyThreadScopeData.getThreadInstance().getAge());

}

}

}

class MyThreadScopeData{

private MyThreadScopeData(){}

public static MyThreadScopeData getThreadInstance(){

MyThreadScopeData instance=map.get();

if(instance==null){

instance=new MyThreadScopeData();

map.set(instance);

}

return instance;

}

private static ThreadLocal map =new ThreadLocal();

private String name;

private int age;

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public int getAge() {

return age;

}

public void setAge(int age) {

this.age = age;

}

}

这里,我们调用MyThreadScopeData的getThreadInstance方法,就可以取得

与当前线程相关的实例对象。

虽然线程结束后也可以自动释放相关的ThreadLocal变量,但是为了优化内存,

我们的ThreadLocal要在线程结束的时候注销,可以调用ThreadLocal.clear()方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值