`

Java中变量的线程安全问题

阅读更多
静态变量:线程非安全。

静态变量即类变量,位于方法区,为所有对象共享,共享一份内存,一旦静态变量被修改,其他对象均对修改可见,故线程非安全。

实例变量:单例模式(只有一个对象实例存在)线程非安全,非单例线程安全。

实例变量为对象实例私有,在虚拟机的堆中分配,若在系统中只存在一个此对象的实例,在多线程环境下,“犹如”静态变量那样,被某个线程修改后,其他线程对修改均可见,故线程非安全;如果每个线程执行都是在不同的对象中,那对象与对象之间的实例变量的修改将互不影响,故线程安全。

局部变量:线程安全。

每个线程执行时将会把局部变量放在各自栈帧的工作内存中,线程间不共享,故不存在线程安全问题。

曾经犯过的错

SimpleDataFormat 是非线程安全的曾经不止一次的使用过将它写成一个静态变量来使用,当时并没有考虑多线程问题,系统也没有出现过错误但是将SimpleDataFormat 作为静态变量来使用是错误的做法。
SimpleDataFormat 源码提到说SimpleDataFormat不是线程安全的。
* Date formats are not synchronized.
* It is recommended to create separate format instances for each thread.
* If multiple threads access a format concurrently, it must be synchronized
* externally.


这是因为里面用了Calendar 这个成员变量来实现SimpleDataFormat,并且在Parse 和Format的时候对Calendar 进行了修改,calendar.clear(),calendar.setTime(date);

所以当SimpleDataFormat使用在多线程的环境中,我们要特别小心,有三种方法来解决这个问题:

1)每次使用时,都创建一个新的SimpleDateFormat实例。如果使用不是很频繁时,可以使用此方法,这样可以降低创建新对象的开销。

2)使用同步:不过,当线程较多时,当一个线程调用该方法时,其他想要调用此方法的线程就要block,这样的操作也会一定程度上影响性能。

3)就是使用ThreadLocal,来确保每个线程只有一个实例如:

class SafeDateForamt {
        static ThreadLocal<DateFormat> threadLocal = new ThreadLocal<DateFormat>() {
            @Override
            protected synchronized DateFormat initialValue() {
               return new SimpleDateFormat("YYYY-MM-DD HH:mm:ss");
            }

        };

        public static Date parse(String dateStr) throws ParseException {
            return threadLocal.get().parse(dateStr);
        }

        public static String format(Date date) {
            return threadLocal.get().format(date);
        }
}
分享到:
评论

相关推荐

    JAVA多线程并发操作全局变量

    NULL 博文链接:https://toknowme.iteye.com/blog/2212529

    Java局部变量线程安全原理分析

    主要介绍了Java局部变量线程安全原理分析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

    java ThreadLocal多线程专属的变量源码

    java ThreadLocal多线程专属的变量源码java ThreadLocal多线程专属的变量源码java ThreadLocal多线程专属的变量源码java ThreadLocal多线程专属的变量源码java ThreadLocal多线程专属的变量源码java ThreadLocal多...

    java多线程_java多线程下变量共享_

    一个简单记录java多线程下变量共享问题,分析多线程内部运行

    java多线程编程总结

    Java线程:线程栈模型与线程的变量 Java线程:线程状态的转换 Java线程:线程的同步与锁 Java线程:线程的交互 Java线程:线程的调度-休眠 Java线程:线程的调度-优先级 Java线程:线程的调度-让步 Java线程:线程的...

    java多线程笔记

    Java线程:线程栈模型与线程的变量 12 Java线程:线程的调度-休眠 13 Java线程:线程的调度-优先级 16 Java线程:线程的调度-让步 19 Java线程:线程的调度-合并 22 Java线程:线程的调度-终止线程 25 Java线程:...

    Java多线程编程总结

    Java线程:线程栈模型与线程的变量 Java线程:线程状态的转换 Java线程:线程的同步与锁 Java线程:线程的交互 Java线程:线程的调度-休眠 Java线程:线程的调度-优先级 Java线程:线程的调度-让步 Java线程...

    java 多线程 加减变量

    java 多线程 加减变量

    线程 JAVA java线程 java线程第3版 java线程第2版第3版合集

    它展示了如何与非线程安全的类共同工作,并特别关注于Swing的线程问题。新增加的一章介绍了如何为多处理器机器编写并行代码。 简而言之,本书的新版涉及了有关线程的方方面面,从最简单的动画applet到最复杂的应用...

    java线程安全测试

    java 线程安全的几个测试小例子,充分的理解JMM中的线程内存模型

    java线程安全性总结

    用思维导图将Java线程安全性相关基本概念联系起来

    java多线程并发

    java多线程并发的在新窗口

    java多线程安全性基础介绍.pptx

    java多线程安全性基础介绍 线程安全 正确性 什么是线程安全性 原子性 竞态条件 i++ 读i ++ 值写回i 可见性 JMM 由于cpu和内存加载速度的差距,在两者之间增加了多级缓存导致,内存并不能直接对cpu可见。 ...

    java多线程通信图解

    java 多线程 其实就是每个线程都拥有自己的内存空间,多线程之间的通信,比例A线程修改了主内存(main方法的线程)变量,需要把A线程修改的结果同步到主线程中,这时B线程再从主线程获取该变量的值,这样就实现了...

    Java 线程总结

    Java线程:线程栈模型与线程的变量 Java线程:线程状态的转换 Java线程:线程的同步与锁 Java线程:线程的交互 Java线程:线程的调度-休眠 Java线程:线程的调度-优先级 Java线程:线程的调度-让步 Java线程:线程的...

    Java的线程安全内存模型.docx

    什么是线程安全问题? 当 多个线程 同时共享同一个 全局变量 做 写 的操作时候,可能会受到其他线程的干扰,导致数据 脏读 。(数据一致性问题) 如何解决线程安全问题? 核心思想:在同一时刻,只能有...

    java线程详解

    Java线程:新特征-条件变量 Java线程:新特征-原子量 Java线程:新特征-障碍器 Java线程:深入ThreadLocal 一、标准例子 二、不用ThreadLocal 三、自己实现个ThreadLocal 四、透过现象看本质 Java线程:大...

    Java 多线程编程面试集锦20道问题解答Java多线程编程高难度面试题及解析

    通过这些高难度问题,您将全面掌握Java多线程编程的核心概念、技术和最佳实践。 每个问题都包含了深入的答案解析,涵盖了多线程编程的各个方面。您将了解线程安全、死锁、线程池、线程上下文切换、线程同步和互斥、...

Global site tag (gtag.js) - Google Analytics