类ThreadLocal的使用

主要解决的是每个线程绑定自己的值,可以将ThreadLocal类比喻成全局存放数据的盒子,盒子中可以存储每个线程私有数据。

类ThreadLocal解决的是变量在不同线程间的隔离线,也就是不同线程拥有自己的值,不同线程中的值是可以放入ThreadLocal类中进行保存的

方法get()与null

package Third;

public class Run {
public static ThreadLocal tl = new ThreadLocal(); public static void main(String[] args) {
if (tl.get() == null) {
System.out.println("从未放过值");
tl.set("我的值");
}
System.out.println(tl.get());
System.out.println(tl.get());
} }

验证线程变量的隔离性

package Third;

public class ThreadA extends Thread {

    @Override
public void run() {
try {
for (int i = 0; i < 100; i++) {
if (Tools.tl.get() == null) {
Tools.tl.set("ThreadA" + (i + 1));
} else {
System.out.println("ThreadA get Value=" + Tools.tl.get());
}
Thread.sleep(200);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
} }
package Third;

public class ThreadB extends Thread {

    @Override
public void run() {
try {
for (int i = 0; i < 100; i++) {
if (Tools.tl.get() == null) {
Tools.tl.set("ThreadB" + (i + 1));
} else {
System.out.println("ThreadB get Value=" + Tools.tl.get());
}
Thread.sleep(200);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
} }
package Third;

public class Tools {

    public static ThreadLocal tl = new ThreadLocal();

}
package Third;

public class Run {

    public static void main(String[] args) {

        try {
ThreadA a = new ThreadA();
ThreadB b = new ThreadB();
a.start();
b.start(); for (int i = 0; i < 100; i++) {
if (Tools.tl.get() == null) {
Tools.tl.set("Main" + (i + 1));
} else {
System.out.println("Main get Value=" + Tools.tl.get());
}
Thread.sleep(200);
}
} catch (InterruptedException e) {
e.printStackTrace();
} } }

每个线程取出自己的数据

package Third;

import java.util.Date;

public class ThreadA extends Thread {

    @Override
public void run() {
try {
for (int i = 0; i < 20; i++) {
if (Tools.tl.get() == null) {
Tools.tl.set(new Date());
}
System.out.println("A " + Tools.tl.get().getTime());
Thread.sleep(100);
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} }
package Third;

import java.util.Date;

public class ThreadB extends Thread {

    @Override
public void run() {
try {
for (int i = 0; i < 20; i++) {
if (Tools.tl.get() == null) {
Tools.tl.set(new Date());
}
System.out.println("B " + Tools.tl.get().getTime());
Thread.sleep(100);
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} }
package Third;

import java.util.Date;

public class Tools {

    public static ThreadLocal<Date> tl = new ThreadLocal<Date>();

}
package Third;

public class Run {

    public static void main(String[] args) {
try {
ThreadA a = new ThreadA();
a.start(); Thread.sleep(1000); ThreadB b = new ThreadB();
b.start();
} catch (InterruptedException e) {
e.printStackTrace();
} } }

怎么实现第一次调用get()不返回null呢?也就是具有默认值的效果

解决get()返回null问题

package Third;

public class ThreadLocalExt extends ThreadLocal {
@Override
protected Object initialValue() {
return "我是默认值 第一次get不再为null";
}
}
package Third;

public class Run {
public static ThreadLocalExt tl = new ThreadLocalExt(); public static void main(String[] args) {
if (tl.get() == null) {
System.out.println("从未放过值");
tl.set("我的值");
}
System.out.println(tl.get());
System.out.println(tl.get());
} }

此案例仅仅证明main线程有自己的值,那其他线程呢?

再次验证线程变量的隔离性

package Third;

public class Tools {
public static ThreadLocalExt tl = new ThreadLocalExt();
}
package Third;

import java.util.Date;

public class ThreadLocalExt extends ThreadLocal {
@Override
protected Object initialValue() {
return new Date().getTime();
}
}
package Third;

public class ThreadA extends Thread {

    @Override
public void run() {
try {
for (int i = 0; i < 10; i++) {
System.out.println("在ThreadA线程中取值=" + Tools.tl.get());
Thread.sleep(100);
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} }
package Third;

public class Run {

    public static void main(String[] args) {
try {
for (int i = 0; i < 10; i++) {
System.out.println(" 在Main线程中取值=" + Tools.tl.get());
Thread.sleep(100);
}
Thread.sleep(5000);
ThreadA a = new ThreadA();
a.start();
} catch (InterruptedException e) {
e.printStackTrace();
}
} }

《Java多线程编程核心技术》读后感(十二)的更多相关文章

  1. Java多线程编程核心技术---对象及变量的并发访问(二)

    数据类型String的常量池特性 在JVM中具有String常量池缓存的功能. public class Service { public static void print(String str){ ...

  2. Java多线程编程核心技术(二)对象及变量的并发访问

    本文主要介绍Java多线程中的同步,也就是如何在Java语言中写出线程安全的程序,如何在Java语言中解决非线程安全的相关问题.阅读本文应该着重掌握如下技术点: synchronized对象监视器为O ...

  3. Java多线程编程核心技术(三)多线程通信

    线程是操作系统中独立的个体,但这些个体如果不经过特殊的处理就不能成为一个整体.线程间的通信就是成为整体的必用方案之一,可以说,使线程间进行通信后,系统之间的交互性会更强大,在大大提高CPU利用率的同时 ...

  4. Java多线程编程核心技术(一)Java多线程技能

    1.进程和线程 一个程序就是一个进程,而一个程序中的多个任务则被称为线程. 进程是表示资源分配的基本单位,线程是进程中执行运算的最小单位,亦是调度运行的基本单位. 举个例子: 打开你的计算机上的任务管 ...

  5. Java多线程编程核心技术---学习分享

    继承Thread类实现多线程 public class MyThread extends Thread { @Override public void run() { super.run(); Sys ...

  6. Java多线程编程核心技术

    Java多线程编程核心技术 这本书有利于对Java多线程API的理解,但不容易从中总结规律. JDK文档 1. Thread类 部分源码: public class Thread implements ...

  7. 《Java多线程编程核心技术》推荐

    写这篇博客主要是给猿友们推荐一本书<Java多线程编程核心技术>. 之所以要推荐它,主要因为这本书写得十分通俗易懂,以实例贯穿整本书,使得原本抽象的概念,理解起来不再抽象. 只要你有一点点 ...

  8. 《java多线程编程核心技术》(一)使用多线程

    了解多线程 进程和多线程的概念和线程的优点: 提及多线程技术,不得不提及"进程"这个概念.百度百科对"进程"的解释如下: 进程(Process)是计算机中的程序 ...

  9. 《Java 多线程编程核心技术》- 笔记

    作为业务开发人员,能够在工作中用到的技术其实不多.虽然平时老是说什么,多线程,并发,注入,攻击!但是在实际工作中,这些东西不见得用得上.因为,我们用的框架已经把这些事做掉了. 比如web开发,外面有大 ...

  10. Thread.currentThread()和this的区别——《Java多线程编程核心技术》

    前言:在阅读<Java多线程编程核心技术>过程中,对书中程序代码Thread.currentThread()与this的区别有点混淆,这里记录下来,加深印象与理解. 具体代码如下: pub ...

随机推荐

  1. RedHat7 防火墙设置以及端口设置

    1.查看防火墙状态,root用户登录,执行命令systemctl status firewalld 2.开启防火墙:systemctl start firewalld 3.关闭防火墙:systemct ...

  2. 我的Java开发学习之旅------>使用循环递归算法把数组里数据数组合全部列出

    面试题如下:把一个数组里的数组合全部列出,比如1和2列出来为1,2,12,21. (面试题出自<Java程序员面试宝典>) 代码如下: import java.util.Arrays; i ...

  3. 【ansible】ansible部署方式以及部署包

    最近研究ansible的使用,在使用pip安装的时候遇到很多奇怪的问题,为此采用了手动安装的方式,并编写了一键安装脚本. ansible要求机器必须安装python2.6以上版本,可以通过一下命令查看 ...

  4. 负载均衡,会话保持,session同步(转)

    一,什么负载均衡一个新网站是不要做负载均衡的,因为访问量不大,流量也不大,所以没有必要搞这些东西.但是随着网站访问量和流量的快速增长,单台服务器受自身硬件条件的限制,很难承受这么大的访问量.在这种情况 ...

  5. 爬虫之重要的requests模块

    一 . requests模块 什么是requests模块 requests模块是python中原生的基于网络请求的模块,其主要作用是用来模拟浏览器发起请求.功能强大,用法简洁高效.在爬虫领域中占据着半 ...

  6. Elasticsearch5 及 head插件 安装说明

    Elasticsearch5.X及 head插件 安装说明: 1.下载elasticsearch安装文件: a) 下载官方源码: https://artifacts.elastic.co/downlo ...

  7. SDUT OJ类型转换函数的应用

    题目描述 处理一个复数与一个double数相加的运算,结果存放在一个double型变量d1中,输出d1的值.定义Complex(复数)类,在成员函数中包含重载类型转换运算符:operator doub ...

  8. ActiveMQ之发布、订阅使用

    maven依赖 <dependencies> <dependency> <groupId>org.apache.activemq</groupId> & ...

  9. RStudio安装package时出现错误

    cannot open URL 'http://www.stats.ox.ac.uk/pub/RWin/src/contrib/PACKAGES' 提示是打不开链接,你切换为国内的源试试Rstudio ...

  10. 基于KD-Tree的最近邻搜索

    目标:查询目标点附近的10个最近邻邻居. load fisheriris x = meas(:,:); figure(); g1=gscatter(x(:,),x(:,),species); %spe ...