线程安全

<span style="font-size:24px;"><strong>举例</strong></span>
比如一个 ArrayList 类,在添加一个元素的时候,它可能会有两步来完成:1. 在 Items[Size] 的位置存放此元素;2. 增大 Size 的值。
在单线程运行的情况下,如果 Size = 0,添加一个元素后,此元素在位置 0,而且 Size=1;
而如果是在多线程情况下,比如有两个线程,线程 A 先将元素1存放在位置 0。但是此时 CPU 调度线程A暂停,线程 B 得到运行的机会。线程B向此 ArrayList 添加元素2,因为此时 Size 仍然等于 0 (注意,我们假设的是添加一个元素是要两个步骤,而线程A仅仅完成了步骤1),所以线程B也将元素存放在位置0。然后线程A和线程B都继续运行,都增加 Size 的值,结果Size都等于1。
那好,我们来看看 ArrayList 的情况,期望的元素应该有2个,而 实际元素是在0位置,造成丢失元素,故Size 等于 1。这就是"线程不安全"了。
 
<span style="font-size:24px;"><strong>概述</strong></span>
<p style="margin-top: 0px; margin-bottom: 12px; padding-top: 0px; padding-bottom: 0px; line-height: 28px; font-family: arial, sans-serif; font-size: 14px;">  如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的。或者说:一个类或者程序所提供的接口对于线程来说是原子操作或者多个线程之间的切换不会导致该接口的执行结果存在二义性,也就是说我们不用考虑同步的问题。线程安全问题都是由全局变量及静态变量引起的。若每个线程中对全局变量、静态变量只有读操作,而无写操作,一般来说,这个全局变量是线程安全的;若有多个线程同时执行写操作,一般都需要考虑线程同步,否则的话就可能影响线程安全。</p><p style="margin-top: 0px; margin-bottom: 12px; padding-top: 0px; padding-bottom: 0px; line-height: 28px; font-family: arial, sans-serif;"><span style="font-size:24px;"><strong>安全性</strong></span></p><p style="margin-top: 0px; margin-bottom: 12px; padding-top: 0px; padding-bottom: 0px; line-height: 28px; font-family: arial, sans-serif; font-size: 14px;"><div class="sonConBox" style="margin: 0px; padding: 0px;"><div class="h2_content" style="margin: -7px 0px 0px; padding: 0px;"><p style="margin-top: 0px; margin-bottom: 12px; padding-top: 0px; padding-bottom: 0px; line-height: 28px;">  类要成为线程安全的,首先必须在单线程环境中有正确的行为。如果一个类实现正确(这是说它符合规格说明的另一种方式),那么没有一种对这个类的对象的操作序列(读或者写公共字段以及调用公共方法)可以让对象处于无效状态,观察到对象处于无效状态、或者违反类的任何不可变量、前置条件或者后置条件的情况。此外,一个类要成为线程安全的,在被多个线程访问时,不管运行时环境执行这些线程有什么样的时序安排或者交错,它必须仍然有如上所述的正确行为,并且在调用的代码中没有任何额外的同步。其效果就是,在所有线程看来,对于线程安全对象的操作是以固定的、全局一致的顺序发生的。     </p><p style="margin-top: 0px; margin-bottom: 12px; padding-top: 0px; padding-bottom: 0px; line-height: 28px;"><h2 style="margin: 20px 0px 20px -20px; padding: 0px; font-size: 14px; font-weight: 500; border-left-width: 10px; border-left-style: solid; border-left-color: rgb(55, 171, 47); clear: both; height: 20px; line-height: 19px; text-indent: 11px; font-family: arial, sans-serif;"><span class="title" style="color: rgb(34, 34, 34); float: left; font-size: 20px; font-family: 'microsoft yahei', Arial, Helvetica, sans-serif; zoom: 1;">安全程度</span><a target=_blank class="conArrow" href="http://baike.haosou.com/doc/6809842-7026796.html#" data-log="h2-title" style="text-decoration: none; background-image: url(http://p0.qhimg.com/t012b40d58f262241ac.png); display: inline; float: right; font-size: 0px; height: 20px; text-shadow: none; width: 20px; background-position: 0px 0px; background-repeat: no-repeat no-repeat;">折叠</a><span class="opt js-edittext" style="border-right-width: 1px; border-right-style: solid; border-right-color: rgb(217, 217, 217); float: right; height: 16px; line-height: 16px; margin: 1px 6px 0px 0px; padding-right: 7px;"><a target=_blank class="edit" href="http://baike.haosou.com/create/edit/?eid=6809842&sid=7026796&secid=4" data-log="edit-btn" style="color: rgb(49, 152, 24); text-decoration: none;"><span class="ico" style="background-image: url(http://p1.qhimg.com/t014d731d1bc6d70129.png); display: inline-block; height: 16px; vertical-align: -5px; width: 16px; background-position: 0px -40px; background-repeat: no-repeat no-repeat;"></span>编辑本段</a></span></h2><div class="sonConBox" style="margin: 0px; padding: 0px; font-family: arial, sans-serif; font-size: 14px; line-height: 28px;"><div class="h2_content" style="margin: -7px 0px 0px; padding: 0px;"><p style="margin-top: 0px; margin-bottom: 12px; padding-top: 0px; padding-bottom: 0px;">线程安全性不是一个非真即假的命题。 Vector 的方法都是同步的,并且 Vector 明确地设计为在多线程环境中工作。但是它的线程安全性是有限制的,即在某些方法之间有状态依赖(类似地,如果在迭代过程中 Vector 被其他线程修改,那么由 Vector.iterator() 返回的 iterator会抛出ConcurrentModifiicationException)。</p><p style="margin-top: 0px; margin-bottom: 12px; padding-top: 0px; padding-bottom: 0px;"></p><p style="margin-top: 0px; margin-bottom: 12px; padding-top: 0px; padding-bottom: 0px;">对于 Java 类中常见的线程安全性级别,没有一种分类系统可被广泛接受,不过重要的是在编写类时尽量记录下它们的线程安全行为。</p><p style="margin-top: 0px; margin-bottom: 12px; padding-top: 0px; padding-bottom: 0px;">Bloch 给出了描述五类线程安全性的分类方法:不可变、线程安全、有条件线程安全、线程兼容和线程对立。只要明确地记录下线程安全特性,那么您是否使用这种系统都没关系。这种系统有其局限性 -- 各类之间的界线不是百分之百地明确,而且有些情况它没照顾到 -- 但是这套系统是一个很好的起点。这种分类系统的核心是调用者是否可以或者必须用外部同步包围操作(或者一系列操作)。下面几节分别描述了线程安全性的这五种类别。</p></div></div></p></div></div><h2 style="margin: 20px 0px 20px -20px; padding: 0px; font-size: 14px; font-weight: 500; border-left-width: 10px; border-left-style: solid; border-left-color: rgb(55, 171, 47); clear: both; height: 20px; line-height: 19px; text-indent: 11px;"><a target=_blank name="6809842-7026796-4" style="color: rgb(19, 110, 194); font-family: arial, sans-serif;"></a></h2></p>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值