《Java多线程编程核心技术》读后感(十二)
类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多线程编程核心技术》读后感(十二)的更多相关文章
- Java多线程编程核心技术---对象及变量的并发访问(二)
数据类型String的常量池特性 在JVM中具有String常量池缓存的功能. public class Service { public static void print(String str){ ...
- Java多线程编程核心技术(二)对象及变量的并发访问
本文主要介绍Java多线程中的同步,也就是如何在Java语言中写出线程安全的程序,如何在Java语言中解决非线程安全的相关问题.阅读本文应该着重掌握如下技术点: synchronized对象监视器为O ...
- Java多线程编程核心技术(三)多线程通信
线程是操作系统中独立的个体,但这些个体如果不经过特殊的处理就不能成为一个整体.线程间的通信就是成为整体的必用方案之一,可以说,使线程间进行通信后,系统之间的交互性会更强大,在大大提高CPU利用率的同时 ...
- Java多线程编程核心技术(一)Java多线程技能
1.进程和线程 一个程序就是一个进程,而一个程序中的多个任务则被称为线程. 进程是表示资源分配的基本单位,线程是进程中执行运算的最小单位,亦是调度运行的基本单位. 举个例子: 打开你的计算机上的任务管 ...
- Java多线程编程核心技术---学习分享
继承Thread类实现多线程 public class MyThread extends Thread { @Override public void run() { super.run(); Sys ...
- Java多线程编程核心技术
Java多线程编程核心技术 这本书有利于对Java多线程API的理解,但不容易从中总结规律. JDK文档 1. Thread类 部分源码: public class Thread implements ...
- 《Java多线程编程核心技术》推荐
写这篇博客主要是给猿友们推荐一本书<Java多线程编程核心技术>. 之所以要推荐它,主要因为这本书写得十分通俗易懂,以实例贯穿整本书,使得原本抽象的概念,理解起来不再抽象. 只要你有一点点 ...
- 《java多线程编程核心技术》(一)使用多线程
了解多线程 进程和多线程的概念和线程的优点: 提及多线程技术,不得不提及"进程"这个概念.百度百科对"进程"的解释如下: 进程(Process)是计算机中的程序 ...
- 《Java 多线程编程核心技术》- 笔记
作为业务开发人员,能够在工作中用到的技术其实不多.虽然平时老是说什么,多线程,并发,注入,攻击!但是在实际工作中,这些东西不见得用得上.因为,我们用的框架已经把这些事做掉了. 比如web开发,外面有大 ...
- Thread.currentThread()和this的区别——《Java多线程编程核心技术》
前言:在阅读<Java多线程编程核心技术>过程中,对书中程序代码Thread.currentThread()与this的区别有点混淆,这里记录下来,加深印象与理解. 具体代码如下: pub ...
随机推荐
- visual studio 2010 c++ 打印 Hello world
由于好奇心驱使温习下c高级简化语言语言(个人解释可能不太准确).下面用visual studio 2010 实现 HelloWord 打印 第一步:visual studio 2010 打开.文件-- ...
- 1 zabbix3.2.4 安装
一. 搭建zabbix服务 Zabbix 3.0对PHP的要求最低为5.4,而CentOS6默认为5.3.3,完全不满足要求,故需要利用第三方源,将PHP升级到5.4以上,注意,不支持PHP7.如下是 ...
- 九度OJ 1047:素数判定 (素数)
时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:9583 解决:4347 题目描述: 给定一个数n,要求判断其是否为素数(0,1,负数都是非素数). 输入: 测试数据有多组,每组输入一个数n ...
- Webpack探索【8】--- 模块热替换详解
本文主要讲模块热替换相关内容.
- python get post模拟请求
1.使用get方式时.url相似例如以下格式: &op=bind GET报问头例如以下: &n=asa HTTP/1.1 Accept: */* Accept-Lang ...
- Swift语言概览
Swift语言概览 关于 这篇文章简要介绍了苹果于WWDC 2014公布的编程语言--Swift. 前言 在这里我觉得有必要提一下Brec Victor的Invent ...
- angularJs-未加载完成的页面显示混乱ng-bind
ng-bind 未初始化完成不加载数据,避免产生{{}}导致页面混乱 还是上边的例子,当前页面没有加载完成的时候,页面显示是不完整的会频繁的出现{{}}这样子的表达式语句,给用户的感觉很不和谐,所以使 ...
- Builder 模式初探
Builder 模式是一步一步创建一个复杂对象的创建型模式,它允许用户在不知道内部构建细节的情况下,可以更精细的控制对象的构造流程.该模式是为了将构建复杂对象的过程和它的部件解耦,使得构建过程和部件的 ...
- VLAN(虚拟局域网)划分
VLAN根据不同的需求,可以有多种划分方式: 一:静态划分 基于端口 按VLAN交换机上的物理端口和内部的PVC(永久虚电路)端口来划分 静态划分安全.可靠,易于配置与维护 二 ...
- HDU 4405 Aeroplane chess:期望dp
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4405 题意: 你在下简化版飞行棋... 棋盘为一个线段,长度为n. 上面有m对传送门,可以直接将你从a ...