
课程咨询: 400-996-5531 / 投诉建议: 400-111-8989
认真做教育 专心促就业
线程问题是许多程序员在学习软件编程开发的时候需要重点关注的一个问题,而本文我们就通过案例分析来简单了解一下,线程安全问题分享。
线程安全
在多线程环境下,保证线程访问的数据的安全格外重要.编写线程安全的代码,本质上就管理状态的访问,而且通常是共享的、可变的状态.
状态:可以理解为对象的成员变量.
共享:是指变量可以被多个线程访问
可变:是指变量的值在生命周期内可以改变.
保证线程安全就是要在不可控制的并发访问中保护数据.
如果对象在多线程环境下无法保证线程安全,就会导致脏数据和其他不可预期的后果
每次调用doSomething()方法的时候,num都会执行自增操作.但是在多线程环境下,这段代码是有问题的.
原因在于num++并不是原子操作,而是由三个离散操作组合而来的:"读-改-写",读取当前的值,加1,写入变量.
可能会出现某一时刻,两个线程同时读到num的数值,然后分别+1,分别写入.这样其中一次计数就不存在了.
有一个专门形容这类情况的名词,叫竞争条件
当计算的正确性依赖于运行时相关的时序或者多线程的交替时,会产生竞争条件.
我对竞争条件的理解就是,多个线程同时访问一段代码,因为顺序的问题,可能导致结果不正确,这就是竞争条件.
这种方式虽然很简单,但是由于synchronized块包住的代码都会顺序的执行,有时会导致令人无法忍受的响应速度
决定synchronized块的大小需要权衡各种设计要求,包括安全性、简单性和性能,其中安全性是绝对不能妥协的,而简单性和性能又是互相影响的(将整个方法声明为synchronized很简单,但是响应速度不太好,将同步块的代码缩小,可能很麻烦,但是性能变好了).
那么在简单性和性能之间我们要如何取舍呢?这里有个原则:通常简单性与性能之间是相互牵制的,实现一个同步策略时,不要过早地为了性能而牺牲简单性(这是对安全性潜在的妥协).
如有耗时长的操作(I/O啊,长时间的计算啊),切记不能放在锁里,否则可能引发活跃度(死锁)与性能(响应慢)的风险.
【免责声明】本文系本网编辑部分转载,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如涉及作品内容、版权和其它问题,请在30日内与管理员联系,我们会予以更改或删除相关文章,以保证您的权益!更多内容请加danei456学习了解。欢迎关注“达内在线”参与分销,赚更多好礼。