用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个字符的字母和 ...
随机推荐
- Test4J与Jtester单元测试常用注解比较
package com.alibaba.ceres.catalog.biz.product.impl; import org.junit.After; import org.junit.Before; ...
- 阿里云的ubuntu server 12.04 下安装jdk和tomcat
因为想自己在做个简单粗暴的小游戏,弄到朋友圈去,买了个阿里云服务,当时选的的ubuntu sever 12.04的os,恰巧朋友又委托一个小项目,所以先尝试搭建下环境. 首先,用putty或者SSH ...
- 当AS3遇见Swift(一)
当AS3遇见Swift 从Hello开始 As3 trace(“Hello Eko”) Swift println(“Hello Eko”) 挺象,有点隔壁王叔叔的意思. 常量和变量 As3 publ ...
- PostgreSQL Replication之第十章 配置Slony(3)
10.3 复制您的第一个数据库 这个小小的介绍之后,我们可以继续前进并复制我们的第一个数据库.要做到这一点,我们可以在一个数据库实例上创建两个数据库.我们想简单地在这两个数据库之间进行复制. [ 您在 ...
- url组成部分
协议 eg:http 主机IP地址 eg :端口号8080 项目资源地址 eg:目录名,文件夹名
- HDU 3686 Traffic Real Time Query System(双连通分量缩点+LCA)(2010 Asia Hangzhou Regional Contest)
Problem Description City C is really a nightmare of all drivers for its traffic jams. To solve the t ...
- Android -- 背景虚化
1,在项目中我们常有这样的需求,就是在个人中心的时候,当用户登录后,要显示用户登陆后的头像,然后背景是用户头像的虚化 ,接下来就来实现一下这个功能,先看一下效果 2,实现起来也挺简单的,没什么难度 , ...
- Windows7 IIS7.5 HTTP Error 503 The service is unavailable 另类解决方案
这篇文章是在你看了别的解决方案仍然解决不了之后才有用. 所以再未用别的解决方案之前,用了该解决方案依然无效的话,请自己看着办. 原创: .net2.0和.net3.5的应用程序池请在开始菜单打开VS2 ...
- eclipse的自动提示功能
一般情况下按ALT+/即可提示,若想按任意字母都有提示,则可以打开eclipse的自动提示功能,打开或关闭该提示功能的步骤如下: 打开eclipse后一次点Window->Perferences ...
- 【sublime】解决汉字输入的办法——InputHelper;在sublime中输入汉字==》InputHelper方法
手工安装办法: cd ~/.config/sublime-text-2/Packages #如果是sublime3就改一下 git clone https://github.com/xgenvn/I ...