java线程——线程局部变量
一,线程局部变量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
①、在多线程的类(如 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线程——线程局部变量的更多相关文章
- Java Thread线程控制
一.线程和进程 进程是处于运行中的程序,具有一定的独立能力,进程是系统进行资源分配和调度的一个独立单位. 进程特征: A.独立性:进程是系统中独立存在的实体,可以拥有自己独立的资源,每个进程都拥有自己 ...
- 多线程(五) java的线程锁
在多线程中,每个线程的执行顺序,是无法预测不可控制的,那么在对数据进行读写的时候便存在由于读写顺序多乱而造成数据混乱错误的可能性.那么如何控制,每个线程对于数据的读写顺序呢?这里就涉及到线程锁. 什么 ...
- 【java】-- 线程池原理分析
1.为什么要学习使用多线程? 多线程的异步执行方式,虽然能够最大限度发挥多核计算机的计算能力,但是如果不加控制,反而会对系统造成负担. 线程本身也要占用内存空间,大量的线程会占用内存资源并且可能会导致 ...
- Java多线程——线程封闭
线程封闭:当访问共享的可变数据时,通常需要同步.一种避免同步的方式就是不共享数据.如果仅在单线程内访问数据,就不需要同步,这种技术称为线程封闭(thread confinement) 线程封闭技术一 ...
- Java之线程与进程
一.线程与进程 线程:一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务.多线程是多任务的一种特别形式,但多线程使用了更小的资源开销. 进程:一个进程包括 ...
- 第一章 - Java与线程
目录 01.Java和线程 02.Java与协程 03.CPU缓存结构和java内存模型 04.管程-悲观锁和锁优化 05.乐观锁 - 无锁方案 06.线程安全 07.线程池 08.JUC 09.高并 ...
- java之线程
java之线程 一:线程: 线程是什么呢?线程,有时被称为轻量级进程是程序执行流的最小单元.一个标准的线程由线程ID,当前指令指针(PC),寄存器集合和堆栈组成.另外,线程是进程中的一个实体,是被系统 ...
- Java 使用线程方式Thread和Runnable,以及Thread与Runnable的区别
一. java中实现线程的方式有Thread和Runnable Thread: public class Thread1 extends Thread{ @Override public void r ...
- Java的线程安全
线程安全 我们这里讨论的线程安全,就限定于多个线程之间存在共享数据访问这个前提,因为如果一段代码根本不会与其他线程共享数据,那么从线程安全的角度来看,程序是串行执行还是多线程执行对它来说是完全没有区别 ...
- 深入理解Java之线程池
原作者:海子 出处:http://www.cnblogs.com/dolphin0520/ 本文归作者海子和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则 ...
随机推荐
- python scipy样条插值函数大全(interpolate里interpld函数)
scipy样条插值 scipy样条插值1.样条插值法是一种以可变样条来作出一条经过一系列点的光滑曲线的数学方法.插值样条是由一些多项式组成的,每一个多项式都是由相邻的两个数据点决定的,这样,任意的两个 ...
- WC2020 联训 #19 矩阵
好不容易自己切一道题 链接 Description 在一个 \(n×(n+1)\) 的棋盘上放棋子, \(n\) 行中每行都恰好有两枚棋子,并且 \(n+1\) 列中每列都至多有两枚棋子,设 \(n= ...
- JuJu团队11月30号工作汇报
JuJu团队11月30号工作汇报 JuJu Scrum 团队成员 今日工作 剩余任务 困难 于达 提供类似generator的数据产生接口 改进代码 对julia不够熟悉 婷婷 和队友一起 ...
- PLC与单片机执行指令区别
单片机执行指令方式与PLC执行指令方式对比 . 映射 对顺序功能图并行分支的理解. PLC与单片机都是顺序执行指令方式的. PLC执行指令分为3个阶段. PLC的一个指令周期包括 输入采样 程序执 ...
- Nachos-Lab2-线程调度模块实现
源码获取 https://github.com/icoty/nachos-3.4-Lab 内容一:总体概述 本实习希望通过修改Nachos系统平台的底层源代码,达到"扩展调度算法" ...
- php.laravel.csrf
概念请自己查 在全局帮助函数库Illuminate\Foundation\helpers.php中有以下几个函数定义,在看过前两个函数实现可以在使用中多少有点帮助. function csrf_fie ...
- Go——标准库使用代理
本文知识点 Go的安装 Go使用代理 Go进阶学习 环境配置 Go的安装 确认环境都安装好了,看看go的版本. go version 代码样例 使用代理,发送GET请求 package main im ...
- JVM探秘:jstack查看Java线程状态
本系列笔记主要基于<深入理解Java虚拟机:JVM高级特性与最佳实践 第2版>,是这本书的读书笔记. jstack命令可以打印Java进程的各个线程堆栈跟踪信息,可以用来查看Java中各个 ...
- 在Ubuntu下搭建Android开发环境(AndroidStudio)
在ubuntu下搭建Android开发环境 本教程的开发环境的搭建有三个大步骤:安装Java jdk,安装Android studio,安装sdk 笔者搭建环境的时候用的是Ubuntu18.04 1. ...
- junit基础学习之-断言注解(3)
断言是编写测试用例的核心实现方式,即期望值是多少,测试的结果是多少,以此来判断测试是否通过. 断言核心方法 assertArrayEquals(expecteds, actuals) 查看两个数组是否 ...