以前的博客提到了“线程安全性”的问题。通常,我们经常说某个类别是线程安全性,其中一些类别是非线程安全性。实际上,线程安全不是“非黑色或白色”单一选择问题。
从“线程安全性”的级别从强度到弱点,我们可以将Java语言中的各种操作和共享数据分为以下5个类别:不变,绝对线程安全性,相对线程安全性,线程安全性,线程兼容性和线程对立。
1.不变
在Java语言中,难以言喻的对象必须是线程安全性。无论是对象的实现方法还是方法的方法,都无需采取任何线程安全保证措施。例如,通过最终关键字修改的数据无法修改并具有最高的可靠性。
2.绝对线程安全
绝对线程安全完全符合Brian Goetz给出的线程安全的定义。这个定义实际上非常严格。一个类都必须实现“无论运行时环境如何,呼叫者通常不需要任何其他同步措施”通常需要支付。
3.相对线安全
相对线程安全是我们通常从意义上说的类别的类是“线程安全性”。
它需要确保此对象的单独操作是安全的。我们在呼叫时不需要采取其他保证措施,但是对于某些特定序列的连续调用,我们可能需要在呼叫上使用其他同步方法来确保呼叫。
在Java语言中,大多数线程安全类是相对线程安全性,例如矢量,空语和集合的SynchronizedCollection()方法的集合。
4.线程兼容性
线程兼容性是我们通常从一般意义上说的一类,它不是线程安全。
线程兼容性意味着对象本身不是线程 - 安全性,但可以用来确保可以正确地使用同步表示对象在并发环境下安全地使用。,收集类ArrayList和Hashmap对应于先前的向量和Hashtable。
5.线相对
线程相反的是指在多线程环境中无法使用的代码,无论呼叫结束是否采用。出现。
线程相反的一个示例是SuperD()和简历()方法的SuperAd类。如果有两个线程同时持有线程对象,一个尝试中断线程,另一个将尝试恢复线程。如果是同时进行的,无论呼叫是否同步,目标线程都会有僵局风险。因为这样做,这两种方法已被放弃。
确保将线程安全性分为同步方法,分为同步方案,无同步解决方案。
1.相互同步
相互同步是最常见的并发方法。同步意味着,当多线程访问共享数据时,可以保证仅在同一时间使用共享数据(同时,只有一个线程正在操作共享共享共享共享数据)。自然排除是实现同步的一种手段。关键部分,相互量和信号量是主要的相互排斥的实施方法。因此,在这四个词中,相互排斥是原因,同步是果实。相互排除是方法,同步是目的。
在Java中,最基本的互斥同步方法是同步关键字。编译了同步关键字后,将在同步块之前和之后形成MonitorEnter和Monitorexit的质量代码质量。参考类型参数指示要锁定和解锁的对象。
此外,重新输入也通过谴责实现同步。根据基本用法,重新输入与同步相似,并且它们都具有相同的线程重新构成特征。
相互排斥同步的主要问题是由线程阻断和觉醒引起的性能问题,因此这种同步也已成为阻止同步。在处理问题的术语中,相互排斥同步是一种悲观的同意策略。我总是认为,只要您不纠正同步措施(例如锁),就会出现问题。在竞争中,它必须锁定。
2.非块同步
随着硬件指令集的开发,出现了基于冲突检测的乐观策略。通常,首先执行操作。如果没有其他线程可以为共享数据而战,则该操作将是成功的;在冲突之后,采用了其他薪酬措施。(最常见的补偿错误是连续重试直到成功)。这些乐观的并发策略中的许多不需要悬挂线,因此此同步操作称为非屏幕同步。
非块实现CAS(CompaArendSwap):CAS指令需要3个操作,即内存地址(了解Java中变量的内存地址,以V表示),旧期望值(由A表示)和新值(B)表示。当执行CAS指令,执行CAS指令时,V符合旧期望值A时,处理器将在V处更新V值,否则将不会执行更新,但是无论是否更新V.在V.上的V值的值,都将返回V的旧值。上面的处理过程是原子操作。
CAS劣势:
ABA问题:因为CAS需要检查操作值期间较低的值是否更改,如果更改不更改,则它已更新,但是该值最初是A,它将变成B,并且会再次变为A。它的价值没有改变,但实际上改变了。
ABA问题的解决方案是使用版本编号。在变量前面的版本编号。每次更新变量时,添加了版本号,然后A-B-A将成为1A-2B-3C.JDK的原子软件包提供一个类AtomicStampedReference来解决ABA问题。该类别的比较方法的作用是首先检查当前参考是否等于预期参考,以及当前符号是否等于预期符号。如果相同的情况相等,则在原子方法中将参考和徽标的值设置为给定的更新值。
3.无需同步解决方案
为了确保线程的安全性,不需要同步,并且两者之间没有因果关系。同时化只是确保共享数据正确性的一种手段。如果方法根本不涉及共享数据,则自然不需要任何同步操作来确保正确性。因此,某些代码是自然而然的。
1)可以重新输入代码
可以重新输入(重新输入码),也称为纯代码,可以在代码执行的任何时刻中断它,而是执行另一个代码。ESSENCEALLre -ESABLED代码是线程-Safe,但并非所有线程安全代码都可以是重复。
重新制定代码的特征是它们不依赖于存储在堆和公共系统资源上的数据,并且使用的状态量是从参数传输的,并且未调用非注册方法。
(主动比率:同步具有锁定功能,即使用同步时,当线程获取对象锁定时,您可以在锁定对象时再次获得对象锁定))
2)线程的本地存储
如果必须与其他代码共享代码部分中所需的数据,则查看这些共享数据代码是否可以确保其在同一线程中执行?如果我们可以保证,我们可以限制在该线程中的可见数据范围相同的线程。这样,无需同步并确保线程之间没有数据纠纷。
对于与此特征一致的应用程序,它并不少见。消费者队列的大多数架构模型(例如“生产者 - 消费者”模型)都会在一个线程中尽可能多地消费产品消耗过程。最重要的应用程序示例是处理方法的处理方法:“一个与一个服务器线程相对应的请求的处理方法“在经典的Web交互模型中。这种处理方法可以使许多Web服务器应用程序使用可以使用线程的线程。本地存储解决线程安全问题。
原始链接:https://blog.csdn.net/qq_26545305/article/details/79516610