文档章节

并发编程实战 1.8. 线程中变量的使用 - ThreadLocal

火犀牛
 火犀牛
发布于 2016/05/11 15:53
字数 911
阅读 15
收藏 0

行业解决方案、产品招募中!想赚钱就来传!>>>

多线程使用同一个Runnable接口实现类的对象,那么所有的线程将共享相同的属性。也就是说,如果在A线程中修改了一个属性,那么所有的线程都会被改变。
如果,对象属性不希望被所有线程共享,可以使用ThreadLocal

范例: 1. 创建线程,每隔一段时间就修改一次里面的成员变量info,并输出。看看线程之间是否有影响。

不安全的:

package com.rr.concurrent.chapter1.recipe7.test;

import java.util.Date;
import java.util.Random;
import java.util.concurrent.TimeUnit;

/**
 * Created by isaac_gu on 2016/5/11.
 */
public class UnsafeTask implements Runnable {

    private String info;

    @Override
    public void run() {
        for (int i = 0, len = 10; i < len; i++) {
            if (null != info) {
                System.out.printf("%s 线程中的info:%s", Thread.currentThread().getName(), info);
            }
            info = String.format("info 被 %s 线程修改!\n", Thread.currentThread().getName());
            try {
                TimeUnit.SECONDS.sleep(new Random().nextInt(10));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

测试:

package com.rr.concurrent.chapter1.recipe7.test;

import java.util.Random;
import java.util.concurrent.TimeUnit;

/**
 * Created by isaac_gu on 2016/5/11.
 * 范例: 1. 创建线程,每隔一段时间就修改一次里面的成员变量info,并输出。看看线程之间是否有影响。
 */
public class UnsafeTest {
    public static void main(String[] args) {

        UnsafeTask unsafeTask = new UnsafeTask();
        //创建三个线程
        for (int i = 0, len = 3; i < len; i++) {
            new Thread(unsafeTask).start();
            try {
                TimeUnit.SECONDS.sleep(new Random().nextInt(3));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }
}

运行结果:

Thread-2 线程中的info:info 被 Thread-2 线程修改!
Thread-0 线程中的info:info 被 Thread-2 线程修改!
Thread-0 线程中的info:info 被 Thread-0 线程修改!
Thread-1 线程中的info:info 被 Thread-0 线程修改!
Thread-2 线程中的info:info 被 Thread-1 线程修改!
Thread-2 线程中的info:info 被 Thread-2 线程修改!
Thread-0 线程中的info:info 被 Thread-2 线程修改!
Thread-2 线程中的info:info 被 Thread-0 线程修改!
Thread-1 线程中的info:info 被 Thread-2 线程修改!

可以看到,info的值被改变后,对所有的线程都是有影响的!

安全的:

package com.rr.concurrent.chapter1.recipe7.test;

import java.util.Random;
import java.util.concurrent.TimeUnit;

/**
 * Created by isaac_gu on 2016/5/11.
 */
public class SafeTask implements Runnable {

    //ThreadLocal<String> info = new ThreadLocal<>();
    //需要初始化,就使用这种方式
    ThreadLocal<String> info = new ThreadLocal<String>() {
        protected String initialValue() {
            return "未赋值";
        }
    };

    @Override
    public void run() {
        for (int i = 0, len = 10; i < len; i++) {
            String info = this.info.get();
            if (null != info) {
                System.out.printf("%s 线程中的info:%s", Thread.currentThread().getName(), info);
            }
            info = String.format("info 被 %s 线程修改!\n", Thread.currentThread().getName());
            this.info.set(info);
            try {
                TimeUnit.SECONDS.sleep(new Random().nextInt(10));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

结果:

Thread-0 线程中的info:未赋值
Thread-1 线程中的info:未赋值
Thread-2 线程中的info:未赋值
Thread-0 线程中的info:info 被 Thread-0 线程修改!
Thread-0 线程中的info:info 被 Thread-0 线程修改!
Thread-0 线程中的info:info 被 Thread-0 线程修改!
Thread-1 线程中的info:info 被 Thread-1 线程修改!
Thread-2 线程中的info:info 被 Thread-2 线程修改!
Thread-1 线程中的info:info 被 Thread-1 线程修改!
Thread-0 线程中的info:info 被 Thread-0 线程修改!
Thread-2 线程中的info:info 被 Thread-2 线程修改!
Thread-2 线程中的info:info 被 Thread-2 线程修改!
Thread-2 线程中的info:info 被 Thread-2 线程修改!

 线程的变量分别为每个线程存储了各个的属性值,并提供给每个线程使用

可以使用get()和set()方法读取修改值。

还有一个 InheritableThreadLocal 类,用于继承中的属性共享。

火犀牛
粉丝 0
博文 27
码字总数 12180
作品 0
海淀
程序员
私信 提问
加载中
请先登录后再评论。
Netty那点事(三)Channel与Pipeline

Channel是理解和使用Netty的核心。Channel的涉及内容较多,这里我使用由浅入深的介绍方法。在这篇文章中,我们主要介绍Channel部分中Pipeline实现机制。为了避免枯燥,借用一下《盗梦空间》的...

黄亿华
2013/11/24
2W
22
访问安全控制解决方案

本文是《轻量级 Java Web 框架架构设计》的系列博文。 今天想和大家简单的分享一下,在 Smart 中是如何做到访问安全控制的。也就是说,当没有登录或 Session 过期时所做的操作,会自动退回到...

黄勇
2013/11/03
3.4K
6
用vertx实现高吞吐量的站点计数器

工具:vertx,redis,mongodb,log4j 源代码地址:https://github.com/jianglibo/visitrank 先看架构图: 如果你不熟悉vertx,请先google一下。我这里将vertx当作一个容器,上面所有的圆圈要...

jianglibo
2014/04/03
4K
3
Flappy Bird(安卓版)逆向分析(一)

更改每过一关的增长分数 反编译的步骤就不介绍了,我们直接来看反编译得到的文件夹 方法1:在smali目录下,我们看到org/andengine/,可以知晓游戏是由andengine引擎开发的。打开/res/raw/at...

enimey
2014/03/04
6K
18
浅入浅出Android(003):使用TextView类构造文本控件

基础: TextView是无法供编辑的。 当我们新建一个项目MyTextView时候,默认的布局(/res/layout/activity_main.xml)中已经有了一个TextView: <TextView 运行效果如下: 修改其文本内容...

樂天
2014/03/22
629
1

没有更多内容

加载失败,请刷新页面

加载更多

用17张 图带你看懂红黑树5大特性

tips:叶子结点,没有子结点的节点。nil等同于java中的null。 根据特点4,得出不能有连续的红色结点,特点5又说从任一结点到每个叶子节点的左右路径都包含相同数目的黑色节点。可以推出最长的路...

小咖呀
今天
0
0
为什么java8还在被大量使用?

  对于很多人来说,新版本的很多功能是很值得期待,并且他是从功能开发到预览一直在关注。而且对于本身来说升级所带来的好处远远大于升级所带来的工作量。   因为java 本身的兼容性问题,...

SXXpenguin
12分钟前
12
0
Yotta企业云盘:企业数据存储的可靠平台

回顾过去的几年,企业云盘市场发生了许多里程碑式的事件。 市场仍在继续进行模式重塑和集成的过程。 行业趋势已经出现,市场在平静中培育了新的机会。 企业在内容管理中的痛点越来越明显,需...

osc_srnunz15
12分钟前
0
0
《剑指 offer》 21. 调整数组顺序使奇数位于偶数前面

点击上方“图解面试算法”,选择“星标”公众号 重磅干货,第一时间送达 大家好,我是程序员吴师兄。 今天分享的题目来源于 LeetCode 上的剑指 Offer 系列 面试题 21.调整数组顺序使奇数位于...

五分钟学算法
今天
0
0
有了这份程序员面试指南,你离大厂Offer还远吗?| 附推荐书籍

本篇文章,我将结合英文版的 Google 面试指南的主线,根据自己的理解对文章进行修改,然后结合自己面试国内大厂的经验给大家阐述。其实我觉得,各大公司针对程序员岗位的面试流程来讲是相对比...

HollisChuang
今天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部