用ThreadLocal为线程生成唯一标识及实现原理
1、在多线程编程中,有时候需要自动为每个启动的线程生成一个唯一标识,这个时候,通过一个ThreadLocal变量来保存每个线程的标识是最有效、最方便的方式了。
2、ThreadLocal 实例通常是类中的私有静态字段
3、在构建ThreadLocal的时候,通过覆盖子类的方法来改写序号。从而达到为每个线程生成序号的目的。
import java.util.Collections;
import java.util.HashMap;
import java.util.Map; /**
* 一个多线程对象,其中有个私有变量SerialNum,用来保存该对象线程的序号
* @author yinchuan.chen
*
*/
class MultiThreadObject extends Thread {
//线程序号变量
private SerialNum serialNum; public MultiThreadObject(SerialNum serialNum) {
//初始化线程序号保存变量
this.serialNum = serialNum;
} /**
* 一个示意性的多线程业务方法
*/
public void run() {
System.out.println("线程" + Thread.currentThread().getName() + "的序号为" + serialNum.getNextNum());
}
} /**
* 一个示意性的ThreadLocal实现,与JDK中ThreadLocal的API对等
* @author yinchuan.chen
*
*/
class SimpleThreadLocal {
//一个线程Map,用来存放线程和其对应的变量副本
private Map threadMap = Collections.synchronizedMap(new HashMap()); public void set(Object object) {
threadMap.put(Thread.currentThread(), object);
} public Object get() {
Thread currentThread = Thread.currentThread();
Object obj = threadMap.get(currentThread);
if (obj == null && !threadMap.containsKey(currentThread)) {
obj = initialValue();
threadMap.put(currentThread, obj);
}
return obj;
} public void remove() {
threadMap.remove(Thread.currentThread());
} protected Object initialValue() {
return null;
}
} /**
* 线程序号标识生成工具
* @author yinchuan.chen
*
*/
class SerialNum {
//类级别的线程编号变量,指向下一个线程的序号
private static Integer nextNum = 0;
//定义一个ThreadLocal变量,存放的是Integer类型的线程序号
// private static ThreadLocal<Integer> threadNo = new ThreadLocal<Integer>() {
private static SimpleThreadLocal threadNo = new SimpleThreadLocal() {
//通过匿名内部类的方式定义ThreadLocal的子类,覆盖initialValue()方法
public synchronized Integer initialValue() {
return nextNum++;
}
}; /**
* 获取线程序号
*
* @return 线程序号
*/
public int getNextNum() {
return (Integer)threadNo.get();
}
} public class TestTreadLocal {
public static void main(String[] args) {
SerialNum serialNum = new SerialNum();
MultiThreadObject m1 = new MultiThreadObject(serialNum);
MultiThreadObject m2 = new MultiThreadObject(serialNum);
MultiThreadObject m3 = new MultiThreadObject(serialNum);
MultiThreadObject m4 = new MultiThreadObject(serialNum); m1.start();
m2.start();
m3.start();
m4.start(); //下面的test方法是在主线程中,当前线程是
testMainThread();
} public static void testMainThread(){
SerialNum serialNum = new SerialNum();
System.out.println("主线程的序号为"+serialNum.getNextNum());
SerialNum serialNum2 = new SerialNum();
System.out.println("主线程的序号为"+serialNum2.getNextNum());
}
}
用ThreadLocal为线程生成唯一标识及实现原理的更多相关文章
- JAVA UUID 生成唯一标识
Writer:BYSocket(泥沙砖瓦浆木匠) 微博:BYSocket 豆瓣:BYSocket Reprint it anywhere u want 需求 项目在设计表的时候,要处理并发多的一些数据 ...
- Python标准库 -- UUID模块(生成唯一标识)
UUID是什么: UUID: 通用唯一标识符 ( Universally Unique Identifier ),对于所有的UUID它可以保证在空间和时间上的唯一性,也称为GUID,全称为: UUID ...
- 用SQL语句生成唯一标识
以前都是在代码中生成GUID值,然后保存到数据库中去,今天发现用sql也能生成GUID值,觉得很新奇,所以记下来. sellect newid(); //得到的即为GUID值 此sql内置函数返回的 ...
- ORACLE生成唯一标识函数
-- Create tablecreate table TAB_TEST( id VARCHAR2(40) not null, fxnum VARCHAR2(40)) ---------------- ...
- 转:C#生成唯一值的方法汇总
这篇文章主要介绍了C#生成唯一值的方法汇总,有需要的朋友可以参考一下 生成唯一值的方法很多,下面就不同环境下生成的唯一标识方法一一介绍,作为工作中的一次总结,有兴趣的可以自行测试: 一.在 .NET ...
- C#生成唯一值的方法汇总
生成唯一值的方法很多,下面就不同环境下生成的唯一标识方法一一介绍,作为工作中的一次总结,有兴趣的可以自行测试: https://www.cnblogs.com/xinweichen/p/4287640 ...
- Flask中的ThreadLocal本地线程,上下文管理
先说一下和flask没有关系的: 我们都知道线程是由进程创建出来的,CPU实际执行的也是线程,那么线程其实是没有自己独有的内存空间的,所有的线程共享进程的资源和空间,共享就会有冲突,对于多线程对同一块 ...
- [转]iOS设备唯一标识探讨
转自:http://www.jianshu.com/p/b83b0240bd0e iOS设备唯一标识探讨 为了统计和检测应用的使用数据,几乎每家公司都有获取唯一标识的业务需求,在iOS5以前获取唯一标 ...
- iOS获取设备唯一标识的各种方法?IDFA、IDFV、UDID分别是什么含义?
一.UDID (Unique Device Identifier) UDID的全称是Unique Device Identifier,顾名思义,它就是苹果IOS设备的唯一识别码,它由40个字符的字母和 ...
随机推荐
- Linux启动时卡住
该系统本是oracle rac的测试环境,在删除oracle软件后重启时系统卡住(没有按照oracle官方要求删除oracle软件).如下图: 处理过程: 1.使用单用户模式登陆 先在GRUB启动菜单 ...
- 学习OpenCV——Kmean(C++)
从前也练习使用过OpenCV的Kmean算法,但是那版本低,而且也是基于C的开发.这两天由于造论文的需要把它重新翻出来在研究一下C++,发现有了些改进 kmeans C++: doublekmeans ...
- Swift游戏实战-跑酷熊猫 10 视差滚动背景
原理 实现 勘误 “实现”的视频中有个错误,如下 背景移动时有个错误,看红色部分,近景归位时,第二张图片的下标是1 if arrBG[0].position.x + arrBG[0].frame.wi ...
- Groupon面经:Find paths in a binary tree summing to a target value
You are given a binary tree (not necessarily BST) in which each node contains a value. Design an alg ...
- Hibernate Annotation笔记
(1)简介:在过去几年里,Hibernate不断发展,几乎成为Java数据库持久性的事实标准.它非常强大.灵活,而且具备了优异的性能.在本文中,我们将了解如何使用Java 5 注释来简化Hiberna ...
- ofbiz进击 第三节。 各个关键文件的说明与作用
1. entityengine.xml 数据引擎文件 用于配置数据库链接设置 <group-map group-name="org.ofbiz" datasource- ...
- URAL 1002 Phone Numbers(KMP+最短路orDP)
In the present world you frequently meet a lot of call numbers and they are going to be longer and l ...
- CentOS 5.5 Nginx+JDK+MySQL+Tomcat(jsp)成功安装案例
在CentOS 5.5中安装Nginx+jdk+mysql+tomcat是非常容易的.只需yum安装环境包和nginx.解压安装jdk和tomcat.配置profile文件.server.xml和ng ...
- $.toJSON的使用方法
我们都会使用jQuery的ajax方法取得json数据但是我们有的时候也要使用json数据给PHP传值,这个怎么做哪? 首先去http://code.google.com/p/jquery-json/ ...
- 夺命雷公狗—angularjs—18—angularjs的事件
对于一款前端框架,提起事件,很容易让人联想到DOM事件,比如说鼠标点击以及页面滚动等.但是我们这里说的angular中的事件和DOM事件并不是一个东西. 事件的发布 我们可以通过 $emit() 以及 ...