二、简介
1.什么是线程安全?
(1)控制多个线程对某个资源的有序访问或修改
(2)如果一个类在多线程的访问下,其状态是可以预测的,并且不需要额外的同步,那么这个类就是线程安全的类
2.为什么要线程安全?
(1)线程不安全会造成数据错误,修正数据错误是费时费力的
(2)线程不安全会导致程序发生一些异常行为,而且这种行为很难查找
(3)线程不安全的现象一般只有在并发量大时才会出现,因此很难重现
三、线程不安全产生原因
1.线程工作内存与主存交互
当线程操作某个共享变量时,可能的执行顺序如下:
(1)从主存复制变量到当前工作内存
(2)执行代码,改变共享变量的值
(3) 将工作内存数据同步回主存
2. 内存可见性与互斥性
(1)可见性:一个线程的执行结果可以被另一个线程所看到
(2)互斥性:在同一时间只能有一个线程对变量的主存进行操作
四、怎样实现线程安全代码?
1.不变对象
(1)它的所有字段都是 final
(2)该类声明为 final
(3)不允许 this 引用在构造期间逸出
(4)任何包含对可变对象(如数组、集合或类似 Date 的可变类)引用的字段:
a.是私有的
b.从来不被返回
c.是对它们所引用对象的唯一引用
d.构造后不会更改被引用对象的状态
2.可变对象
(1)明确共享资源 :类变量、实例变量
(2)利用同步和锁机制 :解决内存的可见性和互斥性
a)synchronized
保证可见性和互斥性
执行顺序如下:
(1)获得同步锁(互斥)
(2)清空线程工作内存
(3)从主存拷贝变量副本到线程工作内存(对本线程可见)
(4)在线程中对变量进行处理
(5)将变量从线程工作内存写回到主存(对其他线程可见)
(6)释放锁(解除互斥)
b)volatile
只保证了可见性
直接操作主存
(1)本线程可以看到其他线程写入的最新结果
(2)其他线程也可以看到本线程写入的最新结果
c)wait,notify,notifyAll
用于线程间进行协调,从而使得共享资源不可能达到不一致的状态,因此共享资源是线程安全的
d) j.u.c包
也包括锁机制(Lock)、协调机制(Condition)
包结构:
(1)线程池
(2)同步集合
(3)锁
(4)原子操作
3. ThreadLocal类
线程本地变量,防止内存泄漏
set(T)
T get()
remove()
ThreadLocal的OOM:非单例类,未调用ThreadLocal.remove造成的Memory Leak
view plain
public class A {
private final ThreadLocal t = new ThreadLocal();
public void a() {
t.set(someObject);
}
public static void main(String[] args) {
while(true) {
new A().a();
}
}
}
五、常见问题
1. 单例类(不要有实例变量)
(1)依靠Spring容器依赖注入的类
(2)Servlet类
2. 常用类(注意其线程安全性描述)
(1)SimpleDateFormat
(2)XPathFactory
view plain
private static final SimpleDateFormat DATE_FORMATTER = new SimpleDateFormat(“yyyy-MM-dd”);
public String formatDate(Date d) {
return DATE_FORMATTER.format(d);
}
六、参考资料
Java Concurrency in Practice
JDK 5.0 Documentation:SimpleDateFormat及XPathFactory的Javadoc
分享到:
相关推荐
为了编写线程安全的代码,通常需要考虑以下几个方面: - **避免使用实例变量**:根据官方指南,编写Struts Action类时,应尽可能避免使用实例变量(非静态非final的成员变量)。这是因为Struts控制器Servlet(通常...
总的来说,编写线程代码需要深入理解多线程的概念,掌握各种创建和管理线程的方法,并确保线程安全和高效性。在实际项目中,结合使用`ExecutorService`和线程池通常是最佳实践,因为它们提供了更好的性能和资源管理...
c#编写串口通讯代码多线程实现,逻辑与界面分离。发送与接收都为单独线程
学习和掌握这些线程安全技术,对于编写高效、稳定的多线程程序至关重要。 总之,线程安全代码块是Java中实现线程同步的一种基本方式,通过`synchronized`关键字,可以保证共享资源在同一时间只被一个线程访问。然而...
总的来说,理解Java内存模型以及其对可见性和有序性的规定,是编写线程安全代码的基础。使用适当的并发工具,如`synchronized`、`volatile`以及原子类,可以帮助开发者有效地解决并发编程中的问题,确保程序在多线程...
本文将深入探讨“简单的线程代码编写”,帮助初学者理解线程的基本概念和如何在代码中实现。 线程是操作系统分配CPU时间片的基本单元,一个进程可以包含多个线程。它们共享同一块内存空间,但各自拥有独立的运行栈...
总之,编写线程安全的JSP程序需要开发者对线程同步有深入理解,并能够适当地使用各种机制来避免并发问题。通过遵循最佳实践和使用合适的工具,可以确保JSP应用程序在多线程环境下的稳定性和可靠性。
通过学习和理解这些概念,并结合提供的"C#编写多线程程序源码"实例,你可以更好地掌握C#中的多线程编程,从而编写出高效、稳定的应用程序。在实际开发中,还需要考虑线程安全、性能优化以及错误处理等细节。
开发者可以通过VS IDE创建项目,编写多线程代码,并利用其强大的调试工具来分析和调试线程行为。在`mthread`这个压缩包中,可能包含了使用上述技术编写的测试代码示例,你可以通过查看和运行这些代码来更好地理解和...
`CreateThread`函数接受多个参数,包括线程安全属性、初始堆栈大小、线程入口点函数、传递给新线程的参数以及线程的创建标志等。在这个例子中,线程的入口点函数是`ThreadProc`,传入的参数是`this`指针,即`...
理解并熟练运用这些概念和技术,可以帮助你在LabWindows/CVI环境中编写出高效且稳定的多线程应用程序,避免因数据不一致或竞态条件而导致的问题。在实践中,要注意合理分配资源,避免死锁,以及对线程性能的优化,...
4. **线程安全**:讨论线程安全函数和数据结构,以及编写线程安全代码的最佳实践。 5. **线程调度策略**:分析各种线程调度算法,如抢占式调度、轮转调度等,以及如何影响程序性能。 6. **异常处理与线程**:讨论...
另一种常见的通信方式是使用 BlockingQueue,如ArrayBlockingQueue、LinkedBlockingQueue等,它们提供了线程安全的插入和移除操作,适合生产者-消费者模型。 五、下载即可运行的线程练习测试代码 提供的"线程测试...
通过编写和执行这样的测试,开发者可以确保他们的代码在并发环境下能够正确地工作,避免潜在的数据不一致性和其他线程安全问题。同时,这也提醒我们在编程时要时刻注意变量的作用域和生命周期,以及它们与多线程环境...
通过学习和理解上述知识点,并结合具体的代码演示(如第一节(多线程通讯代码演示及解决线程安全问题).mp4视频),开发者可以更有效地应对多线程编程中的挑战,编写出高效、稳定的多线程应用程序。
此外,理解线程间的同步原语,如临界区、互斥量、事件和信号量,可以帮助编写更高效、更安全的多线程代码。在Windows环境下,`EnterCriticalSection`和`LeaveCriticalSection`可以用于保护共享资源,`...
通过编写并运行多线程测试用例,可以发现潜在的线程安全问题,然后针对性地进行修复。 总之,理解Java内存模型和掌握线程安全策略对于开发高效、可靠的并发程序至关重要。开发者应始终关注线程安全,确保在多线程...
2. 编写线程安全代码的核心:主要在于处理共享和可变数据,需要考虑一个类是否会被多个线程访问,以及如何保证类的线程安全性。 3. 不可变共享值与多线程:不可变的共享值通常不会引发并发问题,但如果一个不可变...
本资料包“c#编写串口通讯代码 多线程实现.rar”显然关注的是如何在C#中使用多线程技术来实现串口通信,从而提高程序的执行效率和响应性。 串口通信的基本概念: 1. **串行通信**:数据逐位按顺序传输,与并行通信...