ThreadLocal解决SimpleDateFormat多线程安全问题中遇到的困惑
测试代码:
public class Main {
public static void main(String[] args) {
for (int k = 0; k < 10; k++) {
Runnable target = new Runnable() {
@Override
public void run() {
Object obj = dateFormatter.get();
System.out.println(Thread.currentThread().getName() + " => " + obj);
obj = dateFormatter.get();
}
};
new Thread(target, k+"").start();
}
}
private static final ThreadLocal<SimpleDateFormat> dateFormatter = new ThreadLocal<SimpleDateFormat>() {
@Override
protected SimpleDateFormat initialValue() {
return new SimpleDateFormat("yyyy-MM-dd");
}
};
}
输出结果:
8 => java.text.SimpleDateFormat@f67a0200
5 => java.text.SimpleDateFormat@f67a0200
6 => java.text.SimpleDateFormat@f67a0200
...
7 => java.text.SimpleDateFormat@f67a0200
咦?怎么全是f67a0200一个实例?跟踪ThreadLocal代码寻找原因,百思不得其解。最后突然怀疑是SimpleDateFormat中toString方法的问题,SimpleDateFormat#toString源码如下:
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
SimpleDateFormat#hashCode代码如下,其中pattern变量是SimpleDateFormat的格式字符串值( public SimpleDateFormat(String pattern))。
@Override
public int hashCode()
{
return pattern.hashCode();
// just enough fields for a reasonable distribution
}
所以如上原因可以得知,由于自己实现的initialValue方法的SimpleDateFormat的pattern都一样,所以不同sdf实例的toString最终输出相同。
protected SimpleDateFormat initialValue() {
return new SimpleDateFormat("yyyy-MM-dd");
}
产生困惑原因:
通常子类在没有重写toString方法时,我们都可以简单的根据toString值进行判断是否是一个实例,但是由于SimpleDateFormat自己实现了toString所以这个规则不在生效。
提醒:
以后尽可能不要简单的将toString输出用来判断是否是一个实例,如果需要这么判断的话一定要检查toString方法。
拓展:
在java.lang.ThreadLocal#getMap方法中可以发现原来java的Thread对线程局部变量自身就有支持,在Thread中有一个ThreadLocalMap的成员变量。java.lang.ThreadLocal#getMap源码如下:
ThreadLocalMap getMap(Thread t) {
//threadLocals是一个默认修饰符成员变量
return t.threadLocals;
}
ThreadLocal解决SimpleDateFormat多线程安全问题中遇到的困惑的更多相关文章
- 【Java并发编程】12、ThreadLocal 解决SimpleDateFormat非线程安全
大致意思:Tim Cull碰到一个SimpleDateFormat带来的严重的性能问题,该问题主要有SimpleDateFormat引发,创建一个 SimpleDateFormat实例的开销比较昂贵, ...
- 解决SimpleDateFormat线程安全问题
package com.tanlu.user.util; import java.text.DateFormat; import java.text.ParseException; import ja ...
- ThreadLocal 解决simpledateformat线程不安全
SimpleDateFormat在多线程情况下会出现线程不安全的情况,故用ThreadLoacl 处理/** * 用ThreadLocal处理simplDateFormat线程不安全 */public ...
- ThreadLocal解决线程安全问题
一.线程安全问题产生的原因 线程安全问题都是由全局变量及静态变量引起的 二.线程安全问题 SimpleDateFormate sdf = new SimpleDateFormat();使用sdf.pa ...
- NET中解决KafKa多线程发送多主题
NET中解决KafKa多线程发送多主题 一般在KafKa消费程序中消费可以设置多个主题,那在同一程序中需要向KafKa发送不同主题的消息,如异常需要发到异常主题,正常的发送到正常的主题,这时候就需要实 ...
- Spring单例模式多线程安全问题-有状态的Bean
Spring单例与线程安全小结 一.Spring单例模式与线程安全 Spring框架里的bean,或者说组件,获取实例的时候都是默认的单例模式,这是在多线程开发的时候要尤其注意的地方. 单例模式的意思 ...
- ThreadLocal解决了什么问题
小明所在的项目组(迭代组:一直在迭代的路上),经常会在已有接口的基础上开发一些小功能,并且前提是在保证现有用户的不受影响基础上迭代.功能迭代,在代码层面小明有1w种实现方法(吹牛的),一起来看看这次小 ...
- ThreadLocal解决什么问题
原创文章,转载请务必将下面这段话置于文章开头处(保留超链接).本文转发自技术世界,原文链接 http://www.jasongj.com/java/threadlocal/ ThreadLocal解决 ...
- SimpleDateFormat线程安全问题排查
一. 问题现象 运营部门反馈使用小程序配置的拉新现金红包活动二维码,在扫码后跳转至404页面. 二. 原因排查 首先,检查扫码后的跳转链接地址不是对应二维码的实际URL,根据代码逻辑推测,可能是acc ...
随机推荐
- access数据库 配置路径
<configuration> <system.web> <compilation debug="true" targetFramework=&quo ...
- docker 第一次学习(一)--安装以及相关命令
转自:https://www.jianshu.com/p/c69a2a3b4c7a https://docs.docker.com/ http://www.dockerinfo.net/documen ...
- 6.C#知识点:反射
1.反射是什么? 反射提供描述组件,模块和类型的对象(类型为Type).您可以使用反射来动态创建类型的实例,将类型绑定到现有对象,或从现有对象获取类型,并调用其方法或访问其字段和属性.如果您在代码中使 ...
- Oracle问题之ORA-12560TNS:协议适配器错误-转载
作者:@haimishasha本文为作者原创,转载请注明出处:https://www.cnblogs.com/haimishasha/p/5394963.html 目录 Oracle问题之ORA-12 ...
- Contest2071 - 湖南多校对抗赛(2015.03.28)
Contest2071 - 湖南多校对抗赛(2015.03.28) 本次比赛试题由湖南大学ACM校队原创 http://acm.csu.edu.cn/OnlineJudge/contest.php?c ...
- SQL Server系列文章目录
SQL Server系列文章目录SQL Server系列文章目录SQL Server系列文章目录SQL Server系列文章目录
- hadoop的namenode故障处理方法
Namenode 故障后,可以采用如下两种方法恢复数据. 方法一:将 SecondaryNameNode 中数据拷贝到 namenode 存储数据的目录: 方法 二: 使用 -importCheckp ...
- django项目一 CRM表结构
from django.db import models from django.contrib import auth from django.core.exceptions import Perm ...
- 【代码笔记】iOS-NSLog的使用
代码: // 在debug模式下输出NSLog,在release模式下不输出NSLog #ifndef __OPTIMIZE__ #define NSLog(...) NSLog(__VA_ARGS_ ...
- Intellij Idea出现 unable to establish loopback connection
项目一运行就出现这个情况,好几次了,最后发现只要防火墙关闭,项目就可以运行成功.错误提示:“C:\Program Files\Java\jdk1.8.020\bin\java” -Xmx700m -D ...