这礼拜被人问到2次关于action是否是线程安全的?论坛也时常看到有关于线程安全是什么的提问。线程安全到底是什么。现在谈安全,那就是说本来的是不安全的。所以觉得应该转换下问题变成什么是线程不安全。
自己写了个例子,很多线程同时访问一个对象。
测试结果如下
instanceVar是Thread-0 localVar是Thread-0等待...
instanceVar是Thread-1 localVar是Thread-1等待...
等待结束 instanceVar是Thread-1 localVar是Thread-0
等待结束 instanceVar是Thread-1 localVar是Thread-1
从结果的第3行可以看到局部变量是Thread-0,最后类成员却变成Thread-1
得到一个结论:
对象方法中局部变量是在单个线程的工作内存中操作,不共享。
对象成员存在于公共内存中,和所有线程共享。
所以对象成员有可能不会出现本来预想中的值,也就称之为“线程不安全”。
那么具体发生错误的经过是怎么样的呢,为什么要加一句Thread.sleep(1)。
如果注释Thread.sleep(1),那把循环数加到到50。会得到下面的结果
测试结果如下:(太长,只区的局部片断)
instanceVar是Thread-0 localVar是Thread-0等待...
等待结束 instanceVar是Thread-0 localVar是Thread-0
instanceVar是Thread-1 localVar是Thread-1等待...
等待结束 instanceVar是Thread-1 localVar是Thread-1
instanceVar是Thread-2 localVar是Thread-2等待...
等待结束 instanceVar是Thread-2 localVar是Thread-2
instanceVar是Thread-3 localVar是Thread-3等待...
等待结束 instanceVar是Thread-3 localVar是Thread-3
instanceVar是Thread-4 localVar是Thread-4等待...
等待结束 instanceVar是Thread-4 localVar是Thread-4
instanceVar是Thread-5 localVar是Thread-5等待...
instanceVar是Thread-6 localVar是Thread-6等待...
.......(省略)
instanceVar是Thread-47 localVar是Thread-47等待...
instanceVar是Thread-48 localVar是Thread-48等待...
等待结束 instanceVar是Thread-48 localVar是Thread-5
等待结束 instanceVar是Thread-48 localVar是Thread-6
等待结束 instanceVar是Thread-48 localVar是Thread-7
可以看到一开始比较正常,但是一到后来有的线程执行到一半就没有执行,等到线程48执行到一半,原来没有执行完的线程又开始执行。但是对象变量和局部变量却出错了。
这说明
有的线程执行UnSafeObject的process()并没有执行到完毕,时间片就让给了别人,等再次得到时间片的时候,原先的实例变量已经被改变了,所以出现错误。而Thread.sleep是制造了这个过程。
ps:
当前测试环境jdk1.5_9 eclipse,同样的代码在jdk1.5 editplus中会有不同,循环次数加大就可以看到该现象。
写到这里,我突然明白其实这个问题非常简单,就是初学java时介绍同步方法是说的那个问题。但是同步会降低效率。
其实所谓servlet,action的线程安全问题也是这个问题。效率和安全的取舍!
servlet,action如何解决线程安全和效率问题?不采用同步且避免使用类成员
分享到:
相关推荐
**线程安全的理解** 线程安全问题通常发生在多线程环境中,当多个线程同时访问和修改同一份资源时,如果没有适当的同步措施,可能导致程序执行结果与预期不符。线程安全的代码在多线程环境下能够保证正确性,即使不...
首先,我们需要理解线程安全的概念。线程安全意味着当多个线程访问同一段代码时,该代码能正确处理并发操作,不会出现数据不一致或竞态条件等问题。在多线程写入txt日志时,如果没有正确的同步机制,可能会导致日志...
首先,我们要理解线程安全的核心概念。在多线程环境中,当一个资源或操作在被多个线程同时访问时,如果能够确保其行为正确无误,那么我们称这个资源或操作是线程安全的。对于线程安全的双链表,我们需要关注的是链表...
首先,理解线程安全的核心在于避免竞态条件和死锁。竞态条件是指当两个或更多线程可以无序地访问共享数据时,结果的正确性依赖于线程执行的顺序,可能导致不一致的结果。死锁则是指两个或更多的线程相互等待对方释放...
然而,只有深入理解线程安全的概念,并且在设计和实现时谨慎处理共享资源和线程交互,才能编写出高效、稳定且安全的多线程程序。开发人员应当时刻铭记线程安全的重要性,并将其作为设计多线程程序时的首要考虑因素。
为了确保程序在多线程环境下的正确性,理解线程安全性(Thread Safety)至关重要。 #### 2. 线程安全性分析 ##### 2.1 定义与概念 线程安全性是指一个对象或类可以在多线程环境下被多个线程共享而不会导致数据不...
分析这个文件可以帮助我们更好地理解线程安全问题的实际表现和解决方案。 总的来说,理解`SimpleDateFormat`的线程不安全性质是Java开发中的一项重要知识,特别是在设计高并发系统时。开发者应当根据具体需求选择...
总之,理解线程安全容器的实现方式对于编写高效、可靠的多线程应用程序至关重要。正确使用和选择线程安全容器可以避免数据不一致,提高并发程序的稳定性和性能。在实际开发中,可以根据项目需求和性能测试结果,选择...
首先,我们要理解线程安全的基本概念。线程安全是指当多个线程访问同一块资源时,代码能够正确地处理并发情况,不会导致意外的结果。在iOS中,Objective-C和Swift都提供了多种机制来实现线程安全,例如锁(Locks)、...
理解线程安全函数的重要性,并在多线程程序设计中正确使用线程安全的函数或自定义线程安全的函数,是避免竞态条件、确保程序稳定性和可靠性的关键。POSIX标准的规范为开发者提供了指导,确保在开发跨平台的多线程...
理解线程安全的概念并掌握相关的编程技巧是编写高效、可靠的多线程程序的基础。在C++中,通过合理的设计和使用标准库提供的并发工具,可以有效避免线程安全问题,提高软件的健壮性和性能。同时,这些原则和技巧不仅...
然而,多线程环境下也会带来一系列问题,如数据不一致性、资源竞争等,因此,理解线程安全、线程同步以及等待唤醒机制至关重要。此外,单例设计模式在确保一个类只有一个实例的同时,提供了全局访问点,也是多线程...
总之,理解并处理多线程环境下的线程安全问题是提升C#应用程序稳定性和性能的关键。在使用List或其他非线程安全的数据结构时,要时刻警惕潜在的并发问题,并采取适当的同步措施,确保数据的一致性和完整性。
**JAVA内存模型**是理解线程安全的核心。不同的操作系统平台可能有不同的内存管理方式,但Java虚拟机(JVM)提供了一套统一的内存模型来确保跨平台的一致性。Java内存模型主要关注两个方面: 1. **可见性**:当一个...
线程安全是多线程编程中的一个重要概念,它关乎程序在并发执行时的正确性和稳定性。线程安全问题通常出现在共享资源的访问中,当多个线程同时访问和修改同一块内存区域时,如果没有合适的同步机制,就可能出现数据不...
在计算机编程领域,尤其是涉及到实时系统和并发编程时,线程锁和线程安全变量是至关重要的概念。LabWindows/CVI是一种流行的交互式C开发环境,特别适合于开发科学和工程应用。本实例将深入探讨如何在LabWindows/CVI...
但是需要注意,虽然这个方法可以保证基本的线程安全,但迭代仍然是非线程安全的,即不能在遍历过程中修改Map。 2. 使用ConcurrentHashMap:Java从1.5版本开始引入了ConcurrentHashMap,它是线程安全且高并发性能的...
总的来说,理解线程安全和可重入性对于编写高效且可靠的多线程程序至关重要。开发人员需要确保在访问共享资源时采取适当的同步措施,例如使用互斥量、信号量或条件变量,以避免潜在的竞态条件和数据损坏。同时,尽量...
首先,我们需要理解什么是线程安全。线程安全是指在多线程环境下,当多个线程同时访问同一资源时,该资源仍能保持正确的行为。在日志库中,线程安全通常涉及到对日志文件的并发写入和日志级别的同步控制。 在`Log....
在C#编程中,线程是程序执行的基本单元,它...通过这个项目,开发者不仅可以学习到如何操作线程,还能深入理解线程安全和多线程编程中的最佳实践。对于Windows Forms应用开发者来说,这是一个非常有价值的实践案例。