一,线程局部变量ThreadLocal的作用

  用于实现线程内部的数据共享,既对于相同的程序代码,多个模块在同一个线程中运行时要共享一份数据,在另一个线程访问的时候,访问的由是另一份数据。

  每个线程调用ThreadLocal对象的set方法时,就相当于向内部Map集合中增加一条记录。

  Map(key,value)key相当于当前的线程,value相当于set()传递进来的值。

  ThreadLocal<T> threadLocal =new ThreadLocal<T>();  T是set()方法传进来的值类型。

问题:一个ThreadLocal中只能存放一个变量,既其中只能存放一个数据,如果由两个数据,可以定义两个ThreadLocal,但是如果有多个呢?例如100个?

  解决方法是定义一个对象来存放这100个数据,然后在ThreadLocal中存放这个对象。

二,在 Runnable 中创建 ThreadLocal 

在线程类内部创建 ThreadLocal,基本步骤如下: 

  ①、在多线程的类(如 ThreadDemo 类)中,创建一个 ThreadLocal 对象 threadXxx,用来保存线程间需要隔离处理的对象 xxx。

  ②、在 ThreadDemo 类中,创建一个获取要隔离访问的数据的方法 getXxx(),在方法中判断,若ThreadLocal 对象为 null 时候,应该 new()一个隔离访问类型的对象,并强制转换为要应用的类型

  ③、在 ThreadDemo 类的 run()方法中,通过调用 getXxx()方法获取要操作的数据,这样可以保证每个线程对应一个数据对象,在任何时刻都操作的是这个对象。

代码:

package com.itheima.gan;

import java.util.Random;

public class ThreadLocalTest implements Runnable{
//创建一个线程局部变量
ThreadLocal<Student> studentThreadLocal=new ThreadLocal<Student>(); @Override
public void run() {
//获取当前线程的名字
String currentThreadName=Thread.currentThread().getName();
System.out.println(currentThreadName+" is running ...."); //随机生成一个整数
Random random=new Random();
int age=random.nextInt(100); System.out.println(currentThreadName+" is set age:"+age);
//通过这个方法为每一个线程都设置一个独立的student对象
Student student=getStudent();
student.setAge(age); System.out.println(currentThreadName+" is first get age:"+student.getAge()); //线程沉睡
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
} //线程第二次获取年纪
System.out.println(currentThreadName+" is second get age:"+student.getAge());
} private Student getStudent() {
//先获取studnet对象
Student student=studentThreadLocal.get();
//判断对象是否为空,是空的话表示没有给局部变量设置,如果是空的话就在给局部变量重新设置一个值
if(student==null) {
student=new Student();
studentThreadLocal.set(student);
}
return student;
} public static void main(String[] args) {
ThreadLocalTest test=new ThreadLocalTest(); Thread t1=new Thread(test,"线程1");
Thread t2=new Thread(test,"线程2"); t1.start();
t2.start();
} }
class Student{
int age;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age=age;
}
}

  运行结果:

java线程——线程局部变量的更多相关文章

  1. Java Thread线程控制

    一.线程和进程 进程是处于运行中的程序,具有一定的独立能力,进程是系统进行资源分配和调度的一个独立单位. 进程特征: A.独立性:进程是系统中独立存在的实体,可以拥有自己独立的资源,每个进程都拥有自己 ...

  2. 多线程(五) java的线程锁

    在多线程中,每个线程的执行顺序,是无法预测不可控制的,那么在对数据进行读写的时候便存在由于读写顺序多乱而造成数据混乱错误的可能性.那么如何控制,每个线程对于数据的读写顺序呢?这里就涉及到线程锁. 什么 ...

  3. 【java】-- 线程池原理分析

    1.为什么要学习使用多线程? 多线程的异步执行方式,虽然能够最大限度发挥多核计算机的计算能力,但是如果不加控制,反而会对系统造成负担. 线程本身也要占用内存空间,大量的线程会占用内存资源并且可能会导致 ...

  4. Java多线程——线程封闭

    线程封闭:当访问共享的可变数据时,通常需要同步.一种避免同步的方式就是不共享数据.如果仅在单线程内访问数据,就不需要同步,这种技术称为线程封闭(thread  confinement) 线程封闭技术一 ...

  5. Java之线程与进程

    一.线程与进程 线程:一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务.多线程是多任务的一种特别形式,但多线程使用了更小的资源开销. 进程:一个进程包括 ...

  6. 第一章 - Java与线程

    目录 01.Java和线程 02.Java与协程 03.CPU缓存结构和java内存模型 04.管程-悲观锁和锁优化 05.乐观锁 - 无锁方案 06.线程安全 07.线程池 08.JUC 09.高并 ...

  7. java之线程

    java之线程 一:线程: 线程是什么呢?线程,有时被称为轻量级进程是程序执行流的最小单元.一个标准的线程由线程ID,当前指令指针(PC),寄存器集合和堆栈组成.另外,线程是进程中的一个实体,是被系统 ...

  8. Java 使用线程方式Thread和Runnable,以及Thread与Runnable的区别

    一. java中实现线程的方式有Thread和Runnable Thread: public class Thread1 extends Thread{ @Override public void r ...

  9. Java的线程安全

    线程安全 我们这里讨论的线程安全,就限定于多个线程之间存在共享数据访问这个前提,因为如果一段代码根本不会与其他线程共享数据,那么从线程安全的角度来看,程序是串行执行还是多线程执行对它来说是完全没有区别 ...

  10. 深入理解Java之线程池

    原作者:海子 出处:http://www.cnblogs.com/dolphin0520/ 本文归作者海子和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则 ...

随机推荐

  1. Unity 打开其他exe文件

    using UnityEngine; using System.Collections; using System.Diagnostics;///// public class FeiYuZhu : ...

  2. Centos7安装mysql5.7.21

    1.卸载系统自带的 MariaDB [root@CentOS ~]# rpm -qa | grep mariadb mariadb-libs--.el7.x86_64 [root@CentOS ~]# ...

  3. 《ES6标准入门》(阮一峰)--6.正则的扩展

    1.RegExp 构造函数 在 ES5 中,RegExp构造函数的参数有两种情况. 第一种情况是,参数是字符串,这时第二个参数表示正则表达式的修饰符(flag). var regex = new Re ...

  4. ubuntu下pip的安装、升级和使用

    系统虽然自带了不同版本的python,但都没有安装pip,pyhton2.7下使用的是pip2,python3.5下使用的是pip3.下面是各自安装命令. 安装 pip2: sudo apt-get ...

  5. hdu 2578 Dating with girls(1) 满足条件x+y=k的x,y有几组

    Dating with girls(1) Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Oth ...

  6. ProxyPass与ProxyPassReverse及ProxyPassMatch的概述

    转载自:https://blog.csdn.net/xiaokui_wingfly/article/details/51481653 apache中的mod_proxy模块主要作用就是进行url的转发 ...

  7. DW1000芯片定位技术解析

    近些年来随着物联网和机器人技术的大发展,精确定位技术的热度也随之攀升.目前精确定位的技术有很多,如基于wifi.RFID.zigbee.超声波.UWB等技术都可以实现精准定位.由于技术的不同,精度也不 ...

  8. 21 ~ express ~ 内容详情展示 和 阅读数处理

    1,前台 ,/views/main/index.html ,将文章 id 通过url 传送给后台 {% for content in contents %} <div class="p ...

  9. oracle(4)----空值说明

    1. 含义:空值(null)表示未知或者暂时不存在的数据,任何类型(没有约束的条件下)都可以取值null:2. 插入null值: insert into stu (id,name) values(3, ...

  10. 数据备份 rsyncd服务器

    web服务器传文件到备份服务器: 一. rsync备份服务器,yum install -y rsync makdir /etc/rsyncd touch /etc/rsyncd/rsyncd.conf ...