Java高并发程序设计(九)--ThreadLocal

news/2024/7/7 18:42:34 标签: java

如果说锁是让线程有序的争夺资源的话,那么ThreadLocal就是让每个线程都有一份资源。

打个比方,锁是让一百个人争夺一只笔区写字,ThreadLocal就是一百个人每人都有一只笔,在轮到他们写字的时候写。

写个简单的例子:

public class demo implements Runnable{
    static ThreadLocal<test> tl=new ThreadLocal<test>();
    static class test 
    {
        private Integer in;
        public Integer getIn() {return in;}
        test(Integer in){this.in=in;}
    }
    public static void main(String[] args) {
        ExecutorService es=Executors.newFixedThreadPool(10);
        for(int i=0;i<100;i++)
        {
            es.submit(new demo());
        }
    }
    public void run() {
        tl.set(new test(new Random().nextInt(100)));
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(tl.get().getIn());
    }
}

Demo里有一个test内部类,有一百个线程,每个线程都有一个test类存在ThreadLocal那里,每个线程访问自己的test,互不影响。

 

接下来来看ThreadLocal的原理,从set()方法看起:

 public void set(T value) {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null)
            map.set(this, value);
        else
            createMap(t, value);
    }

首先获得现在工作的线程,再获得一个ThreadLocalMap,ThreadLocalMap是它的内部类:

static class ThreadLocalMap {
        static class Entry extends WeakReference<ThreadLocal> {
            Object value;

            Entry(ThreadLocal k, Object v) {
                super(k);
                value = v;
            }
        }
、、、、、、、、、 }

可以把它看做和HashMap类似的东西,用ThreadLocal作为key,

然后进入getMap()方法:

ThreadLocalMap getMap(Thread t) {
        return t.threadLocals;
    }

直接获得线程的threadLocals,进入Thread,

ThreadLocal.ThreadLocalMap threadLocals = null;

可以看到Thread维护了一个ThreadLocal.ThreadLocalMap,回到set方法,现在我们知道getMap()获得一个有Thread维护的ThreadLocal内部类,现在它为空,进入else,进入createMap():

void createMap(Thread t, T firstValue) {
        t.threadLocals = new ThreadLocalMap(this, firstValue);
    }

给Thread中的threadLocals赋值,自己本身作为key,需要维护的值作为Value。

 

看完set方法,接下来看get()方法:

public T get() {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null) {
            ThreadLocalMap.Entry e = map.getEntry(this);
            if (e != null)
                return (T)e.value;
        }
        return setInitialValue();
    }

很简洁明了,从map里面获得value,没什么好说的,想了解更详细的可以自己看源码。

 

另外,因为threadLocals的引用是在Thread里面,Thread不退出,意味着它会一直存在,而且如果是由线程池维护线程,线程可能不会退出。

所以最好习惯性用完之后,调用remove()方法。

 

转载于:https://www.cnblogs.com/blogofjzq/p/9437344.html


http://www.niftyadmin.cn/n/1440850.html

相关文章

关闭端口防止病毒与黑客入侵(转)

你的系统是不是1XP SP1&#xff0c;但是安装了2005瑞星杀毒软件后总是提示系统有 MS-4011 Exploit 和Blaster Rpc Exploit 两个漏洞。。。。。。。    最直接的办法&#xff0c;把系统不用的端口都关闭掉&#xff0c;然后从新启动&#xff0c;如果瑞星还提示有漏洞攻击&…

移动通信概要(转)

摘要&#xff1a;移动通信网在世纪之交正以前所未有的高速度发展。本文扼要探讨其现状与展望&#xff0c;简要介绍蜂窝移动通信网、卫星移动通信网和移动数据通信网的技术应用及其演进情况。关键词&#xff1b;移动通信 GSM CDMA卫星通信 CDPD GPRS一、引言当前全球移动通信正以…

实例解析:高效率网吧组网解决方案(转)

目前国内最为常见的网吧网络规模在100台电脑到400台电脑之间。考虑到此类网吧网络的建设已形成规模&#xff0c;中心选择高性能的全千兆交换机形成一个千兆的交换网络是十分必要的。同时考虑到为确保整个网络的高效率使用&#xff0c;全网配置提供丰富管理功能的可网管交换机也…

数据库设计的三大范式

简介 为了建立冗余较小&#xff0c;结构合理的数据库&#xff0c;设计数据库时必须遵守一定的规则&#xff0c;在关系型数据库中这种规则就是范式。范式是符合某一种级别的关系模式的集合。关系型数据库中的关系必须满足一定的要求&#xff0c;即满足不同的范式。 目前关系型…

如何防范短信接口被恶意调用(被刷)

鉴于之前遇到过短信接口被刷的问题&#xff0c;解决的不是很好。现发现一篇如此高质量博客&#xff0c;特此收藏分享~ 一、什么是短信轰炸&#xff08;短信接口被刷&#xff09; 短信轰炸一般基于 WEB 方式(基于客户端方式的原理与之类似)&#xff0c;由两个模块组成&#xff0…

Peeking in MySQL 5.0 Enterprise Functional(转)

Peeking in MySQL 5.0 Enterprise Functional&#xff1a; MySQL5.0 Alpha 發佈, 我們期待已久的 Create Function 和 Create Procedure 的功能終於有了. 詳細的資訊請參考 MySQL AB 的官方網站的 新聞. 早就想要的功能,出來了還不趕快試試....本文以 Windows XP PRO os 為例&l…

[转帖] 运维自动化

原贴地址&#xff1a; http://www.cnblogs.com/wangxiaoqiangs/p/5685239.html 简介&#xff1a; 当下有许多的运维自动化工具( 配置管理 )&#xff0c;例如&#xff1a;Ansible、SaltStack、Puppet、Fabric 等。 Ansible 一种集成 IT 系统的配置管理、应用部署、执行特定任务的…

J2ME学习笔记(五)(转)

一开始谈事务处理肯定就以为各式各样不同的概念&#xff0c;java基类的继承等东西。所以感觉很是枯燥。以 前学java的时候一谈事务处理我就头痛。呵呵。 呵呵&#xff0c;开始研究一下MIDlet的事务处理咯。其实以前也没有写过Applet&#xff0c;但是Servlet倒是写得多&#xff…