`

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);
        }
}
分享到:
评论

相关推荐

    局部变量线程安全测试

    描述中提到的源码测试可能包含以下内容:创建多个线程,每个线程执行一个包含局部变量的方法,然后观察结果以确定是否存在线程安全问题。测试可能包括对局部变量的读写操作,以及涉及到同步机制如synchronized关键字...

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

    通过对Java局部变量线程安全原理的分析,我们可以更好地理解Java的线程安全机制,避免在编程中出现线程安全问题。 局部变量线程安全原理 Java局部变量线程安全原理是基于每个线程都有自己独立的方法调用栈结构的...

    java线程安全测试

    在Java中,线程安全问题通常与并发、内存模型和可见性有关。Java内存模型(JMM)定义了如何在多线程环境下共享数据的规则,确保线程之间的正确交互。 线程安全可以分为三种类型: 1. 不安全:当多个线程访问共享...

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

    在多线程环境中,变量共享是一个常见的需求,但也是引发问题的关键点。本篇文章将深入探讨Java多线程下变量共享的问题以及解决策略。 在Java中,线程共享变量可以通过两种方式实现:静态成员变量和实例成员变量。...

    Java多线程 - (一) 最简单的线程安全问题

    总之,理解并掌握Java中的线程安全问题及其解决方案是每个Java开发者必备的技能,这不仅可以确保程序的正确性,还能有效利用多核处理器,提升系统性能。在阅读源码时,也要注意观察作者如何处理线程安全,这对于提升...

    servlet线程安全问题

    Servlet 的线程安全问题主要是由于实例变量使用不当而引起的。例如,在一个 Servlet 中定义了一个实例变量 output,在 service 方法将其赋值为用户的输出。当一个用户访问该 Servlet 时,程序会正常的运行,但当多个...

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

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

    servlet与Struts action线程安全问题分析

    Servlet和Struts Action是两种常见的Java Web开发组件,它们在多线程环境下运行时可能存在线程安全问题。线程安全是指在多线程环境中,一个类或者方法能够正确处理多个线程的并发访问,保证数据的一致性和完整性。 ...

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

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

    Java 单例模式线程安全问题

    若每个线程中对全局变量、静态变量只有读操作,而无写操作,一般来说,这个全局变量是线程安全的。若有多个线程同时执行写操作,一般都需要考虑线程同步,否则就可能影响线程安全。 在 Java 中,有状态的 Bean 是非...

    Java多线程-线程的安全问题与线程的同步机制介绍

    但是如果多个线程中对资源有读和写的操作,就容易出现线程安全问题。 (2)同一个资源问题和线程安全问题 举例:“多线程的安全问题”是因为多线程对统一资源进行读和写操作时带来的。例如,火车站卖票的过程。...

    关于如何解决HashMap线程安全问题的介绍

    4. 避免在多线程环境中直接使用HashMap:如果你确定不需要在多线程环境下共享HashMap,那么可以考虑局部变量的方式,只在单个线程中使用HashMap,这样就无需担心线程安全问题。 总结起来,理解HashMap的线程不安全...

    Java并发中的线程安全性

    ### Java并发中的线程安全性 #### 1. 引言 随着Java技术的发展以及多核处理器的普及,Java并发编程成为软件开发中的一个重要领域。Java并发控制问题是国内外学者研究的热点之一,特别是在J2SE 1.5版本中引入了`...

    java线程安全总结.doc

    Java中的线程安全问题通常表现为竞态条件、死锁、活锁和饥饿现象。 ### 二、线程安全的分类 1. **无状态对象**:对象的状态不会被任何线程修改,因此它们天生线程安全。 2. **线程不安全对象**:对象的状态可以被...

    Java中的线程安全与线程同步.doc

    线程安全问题通常出现在共享变量的访问中,例如上述文档中提到的“抢优惠”例子,如果没有适当的同步措施,可能会导致同一优惠号码被多次获取,甚至出现负数或0的情况。 为了解决这些问题,Java提供了多种线程同步...

    多线程线程变量赋值

    线程局部变量主要用于在不同线程中保持独立的状态,而不是作为共享数据的媒介。 在实际开发中,合理使用线程局部变量可以提高程序的并发性能,减少不必要的同步开销。但是,过度依赖线程局部变量可能会导致内存泄漏...

    Java多线程-线程安全问题练习题

    在Java多线程编程中,线程安全问题是非常关键的概念,它涉及到多个线程访问共享资源时可能出现的数据不一致或异常情况。本题主要通过两个练习题来加深对线程安全的理解。 ### 练习题1:新年倒计时 #### 题目描述 ...

    java 多线程 加减变量

    java 多线程 加减变量

Global site tag (gtag.js) - Google Analytics