文档章节

Java并发编程初级篇(八):ThreadLocal

阿拉德大陆的魔法师
 阿拉德大陆的魔法师
发布于 2016/11/23 16:30
字数 670
阅读 45
收藏 1
点赞 0
评论 0

 

在Java中,如果使用了Runnable接口的实现类。用这个实现类的一个实例对象来启动多个线程,那么这个类中的变量就会被多个线程共用,不管你住没注意,这在“Java并发编程(一):线程实现与运行的两种方式”中已经出现过了。

我们现在基于这个例子来改造一下,看如何用一个Runnable的实例对象创建多个线程类,并且让每一个线程都有自己的私有属性。

我们用Java API提供的ThreadLocal类来替换int变量,ThreadLocal类作为Java API提供的一个线程局部变量,它是和线程绑定的,每一个线程都会有一个独立的副本。

通过查看ThreadLocal类的原代码,我们可以发现每一个线程内部都会有一个ThreadLocalMap属性,这个类的内部实现是一个Entry[]数组,(key=ThreadLocal,value=ThreadLocal对象的绑定值)。当你调用ThreadLocal.get()方法的时候,它就会获取当前线程对象的ThreadLocalMap属性中以ThreadLocal对象为健对应的值。如果不存在就会调用setInitialValue()方法,然后将initialValue()方法返回的值设置到ThreadLocalMapEntry[]数组中,并返回这个值。

/**
     * Returns the value in the current thread's copy of this
     * thread-local variable.  If the variable has no value for the
     * current thread, it is first initialized to the value returned
     * by an invocation of the {@link #initialValue} method.
     *
     * @return the current thread's value of this thread-local
     */
    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();
    }

/**
     * Variant of set() to establish initialValue. Used instead
     * of set() in case user has overridden the set() method.
     *
     * @return the initial value
     */
    private T setInitialValue() {
        T value = initialValue();
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null)
            map.set(this, value);
        else
            createMap(t, value);
        return value;
    }

下面看我们的实现代码,为线程定义一个ThreadLocal类型属性,具体实现ThreadLocal中的initialValue()方法来为这个ThreadLocal对象属性赋一个初始值。然后使用MyRunnable的一个实例启动三个线程。

public class MyRunnable implements Runnable {
    private ThreadLocal<Integer> num = new ThreadLocal<Integer>(){
        @Override
        protected Integer initialValue() {
            return 3;
        }
    };

    @Override
    public void run() {
        while (num.get() > 0) {
            System.out.println("Thread:" + Thread.currentThread().getName() + ", consume " + num.get());
            num.set(num.get() - 1);
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        Runnable runnable = new MyRunnable();

        Thread thread1 = new Thread(runnable);
        Thread thread2 = new Thread(runnable);
        Thread thread3 = new Thread(runnable);

        thread1.start();
        thread2.start();
        thread3.start();
    }
}

查看控制台日志,你会发现每一个线程都使用了一个独立的num值。

Thread:Thread-0, consume 3
Thread:Thread-2, consume 3
Thread:Thread-1, consume 3
Thread:Thread-0, consume 2
Thread:Thread-1, consume 2
Thread:Thread-2, consume 2
Thread:Thread-2, consume 1
Thread:Thread-1, consume 1
Thread:Thread-0, consume 1

 

© 著作权归作者所有

共有 人打赏支持
阿拉德大陆的魔法师
粉丝 20
博文 91
码字总数 83019
作品 0
西城
程序员
干货系列1:Java互联网网站开发工程师 的技术提高与晋升路线(技术专精)

前几天写了自己对于Java软件开发工程师职业发展规划方面的一些感悟,陆续收到一些反馈,希望我能再就Java工程师不同的开发(职责)方向谈谈职业发展问题。(上一篇:Java软件开发工程师的自我...

半饱即好
06/26
0
0
安卓开发必备知识体系:Java篇

大家好我是张拭心,自从各位朋友帮点广X开始,我发现我每天更有奔头了,走起路来也更有劲了,说啥也得更新的勤快一点。不过放心,我一定推送有价值的内容给大家,还请朋友们照旧动动手指点点...

d29h1jqy3akvx
05/10
0
0
读书笔记之《Java并发编程的艺术》-并发编程容器和框架(重要)

读书笔记部分内容来源书出版书,版权归本书作者,如有错误,请指正。 欢迎star、fork,读书笔记系列会同步更新 git https://github.com/xuminwlt/j360-jdk module j360-jdk-thread/me.j360....

Hi徐敏
2015/11/11
0
1
读书笔记之《Java并发编程的艺术》-并发编程基础

读书笔记部分内容来源书出版书,版权归本书作者,如有错误,请指正。 欢迎star、fork,读书笔记系列会同步更新 git https://github.com/xuminwlt/j360-jdk module j360-jdk-thread/me.j360....

Hi徐敏
2015/11/11
0
8
Java:ConcurrentHashMap的实现机制

探索 ConcurrentHashMap 高并发性的实现机制 Java并发编程之ConcurrentHashMap 聊聊并发(四)——深入分析ConcurrentHashMap 上面的三篇分析是针对java7的,java8中的实现方式已经变化。...

樂天
2015/06/28
0
0
《Java从小白到大牛精简版》之第1章 开篇综述

Java诞生到现在已经有20多年了,但是Java仍然是非常热门的编程语言之一,很多平台中使用Java开发。表1-1所示的是TIOBE社区发布的2016年5月和2017年5月的编程语言排行榜,可见Java语言的热度,...

tony关东升
06/26
0
0
读书笔记之《Java并发编程的艺术》-线程池和Executor的子孙们

读书笔记部分内容来源书出版书,版权归本书作者,如有错误,请指正。 欢迎star、fork,读书笔记系列会同步更新 git https://github.com/xuminwlt/j360-jdk module j360-jdk-thread/me.j360....

Hi徐敏
2015/11/11
0
1
Java 使用 happen-before 规则实现共享变量的同步操作

前言 熟悉 Java 并发编程的都知道,JMM(Java 内存模型) 中的 happen-before(简称 hb)规则,该规则定义了 Java 多线程操作的有序性和可见性,防止了编译器重排序对程序结果的影响。按照官方的...

stateIs0
01/20
0
0
Java 编程之美:并发编程高级篇之一

本文来自作者 追梦 在 GitChat 上分享 「Java 编程之美:并发编程高级篇之一」 编辑 | 工藤 前言 借用 Java 并发编程实践中的话:编写正确的程序并不容易,而编写正常的并发程序就更难了。 ...

gitchat
05/24
0
0
【转】15个顶级Java多线程面试题及回答

Java 线程面试问题   在任何Java面试当中多线程和并发方面的问题都是必不可少的一部分。如果你想获得任何股票投资银行的前台资讯职位,那么你应该准备很多关于多线程的问题。在投资银行业务...

一只死笨死笨的猪
2014/09/30
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

大数据教程(2.11):keeperalived+nginx高可用集群搭建教程

上一章节博主为大家介绍了目前大型互联网项目的系统架构体系,相信大家应该注意到其中很重要的一块知识nginx技术,在本节博主将为大家分享nginx的相关技术以及配置过程。 一、nginx相关概念 ...

em_aaron
7分钟前
0
0
Apache Directory Studio连接Weblogic内置LDAP

OBIEE默认使用Weblogic内置LDAP管理用户及组。 要整理已存在的用户及组,此前办法是导出安全数据,文本编辑器打开认证文件,使用正则表达式获取用户及组的信息。 后来想到直接用Apache Dire...

wffger
14分钟前
0
0
HFS

FS,它是一种上传文件的软件。 专为个人用户所设计的 HTTP 档案系统 - Http File Server,如果您觉得架设 FTP Server 太麻烦,那么这个软件可以提供您更方便的档案传输系统,下载后无须安装,...

garkey
19分钟前
0
0
STM 32 窗口看门狗

http://bbs.elecfans.com/jishu_805708_1_1.html https://blog.csdn.net/a1985831055/article/details/77404131...

whoisliang
昨天
0
0
Dubbo解析(六)-服务调用

当dubbo消费方和提供方都发布和引用完成后,第四步就是消费方调用提供方。 还是以dubbo的DemoService举例 -- 提供方<dubbo:application name="demo-provider"/><dubbo:registry address="z...

青离
昨天
1
0
iptables规则备份和恢复、firewalld的9个zone以及操作和service的操作

保存以及备份iptalbes规则 设定了的防火墙规则要进行保存,否则系统重启后这些规则就没有了,使用命令 ”service iptables save ” 会把设定好的防火墙规则保存到文件/etc/sysconfig/iptabl...

黄昏残影
昨天
0
0
k8s image

k8s.gcr.io/kube-apiserver-amd64:v1.11.0k8s.gcr.io/kube-controller-manager-amd64:v1.11.0k8s.gcr.io/kube-scheduler-amd64:v1.11.0k8s.gcr.io/kube-proxy-amd64:v1.11.0k8s.gcr.......

分秒
昨天
0
0
数据结构--排序

这篇博客包含了数据结构中多种的排序算法: (1)简单选择:第一趟在A[0]~A[n-1]之间找到最小的,与A[0]进行交换,之后在A[1]~A[n-1]之间进行。。。第i趟在A[i-1]~A[n-1]之间找到最小的,最后...

wangxuwei
昨天
1
0
一名3年工作经验的java程序员应该具备的职业技能

一名3年工作经验的Java程序员应该具备的技能,这可能是Java程序员们比较关心的内容。我这里要说明一下,以下列举的内容不是都要会的东西—-但是如果你掌握得越多,最终能得到的评价、拿到的薪...

老道士
昨天
3
0
MAC安装JDK

一 :在JDK官网下载对应的JDK版本 http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 二:找到JDK安装目录,点击会出现图标,双击图标自动安装,勾选默...

WALK_MAN
昨天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部