当前位置:   article > 正文

Java线程安全_substring是线程安全吗

substring是线程安全吗

1.线程安全

首先介绍一下Java语言中各种操作共享的数据,具体可分为以下5类:不可变、绝对线程安全、相对线程安全、线程兼容和线程对立。

  • 不可变
    “不可变”带来的安全性是最简单和最纯粹的。在Java中,如果一个共享数据是基本数据类型,那么只要在定义时使用final关键字修饰就可以保证它是不可变的。如果共享数据是一个对象,那就需要保证对象的行为不会对其状态产生任何影响,比如String类的对象,它就是一个典型的不可变对象,调用它的substring()、replace()和concat()方法时不会影响原来的值,只会返回一个新构造的字符串。最简单保证对象行为不影响自己状态的方法就是把带状态的变量声明为final。
    注:同为Number的子类型的原子类AtomicInteger和AtomicLong是可变的。
  • 绝对线程安全
    绝对的线程安全指的是满足“不管运行时环境如何,调用者都不用任何额外的同步措施”,在JavaAPI中标注自己是线程安全的类大多都不是绝对的线程安全。
  • 相对线程安全
    相对的线程安全就是通常意义上的线程安全,它需要保证对该对象单独的操作是线程安全的,在调用时不需要额外的保障措施,但对于一些特定顺序的连续调用就可能在调用端使用额外的同步手段保证调用的正确性。
  • 线程兼容
    线程兼容指对象本身不是线程安全的,但可以通过在调用端正确使用同步手段保证对象在并发环境中可以安全的使用。
  • 线程对立
    指无论调用端是否采取了同步措施,都无法在多线程环境中并发使用的代码, 应尽量避免这种代码的出现。

2.线程安全的实现方法

  • 互斥同步
    同步是指在多个线程并发访问共享数据时,保证共享数据在同一个时刻只被一个(或者是一些,使用信号量的时候)线程使用。互斥是实现同步的一种手段,临界区、互斥量、信号量都是主要的互斥实现方式。因此,互斥是因,同步是果;互斥是方法,同步是目的。
    最基本的互斥同步手段就是
    synchronized
    关键字,synchronized关键字经过编译后会在同步块前后分别形成monitorenter和monitorexit两个字节码指令,这两个字节码指令都需要一个reference类型的参数指明要锁定和解锁的对象。
    另外可以使用同步锁实现同步,也具备线程重入特性,另外增加了等待可中断、可实现公平锁以及锁可绑定多个条件
    等待可中断指当前持有锁的线程长期不释放锁的时候,正在等待的线程可以选择放弃等待,改为处理其他事情,可中断特性对处理执行时间非常长的同步块很有帮助。
    公平锁指多个线程在等待同一个锁时,必须按照申请锁的时间顺序依次获得锁;synchronized中的锁时非公平的,同步锁默认也是非公平的,但可以通过带布尔值的构造参数要求使用同步锁。
    锁绑定多个条件是指一个ReentrantLock对象可以同时绑定多个Condition对象。
    注:优先考虑使用synchronized进行同步。
  • 非阻塞同步
    从处理问题的方式上说,互斥同步属于一种悲观的并发策略。随着硬件指令集的发展,我们可以选择基于冲突检测的乐观并发策略,通俗的说,就是先进行操作,如果没有其他线程争用共享数据,那就操作成功;如果有争用,产生了冲突,那就再采取其他的补偿措施,这种乐观的并发策略的许多实现都不需要把线程挂起,也被称为非阻塞同步。
    使用乐观并发策略需要操作和冲突检测具备原子性,硬件保证一个从语义上看起来需要多次操作的行为只通过一条处理器指令就能完成,常用指令有:测试并设置(Test-and-Set)、获取并增加(Fetch-and-Increment)、交换(Swap)、比较并交换(Compare-ans-Swap)、加载链接/条件存储(LL/SC)
  • 无同步方案
    保证线程安全并不是一定要进行同步,例如一个方法没有涉及共享数据,那就无须任何同步措施去保证正确性,有一些代码天生就是线程安全的。
    可重入代码:也叫纯代码,可以在执行的任何时刻中断,转而去执行另外一段代码,在控制权返回后原来的程序不会出现任何错误。
    线程本地存储:如果一段代码中所需要的数据必须与其他代码共享,那就保证这些共享数据的代码在同一个线程中执行。

3.锁优化

  • 自旋锁和自适应自旋
    物理机器上有一个以上的处理器,能让两个或以上的线程同时并行执行,就可以让后面请求锁的线程“稍等一下”,但不放弃处理器的执行时间,看看持有锁的线程是否很快就会释放锁。为了让线程等待,我们只需让线程执行一个忙循环(自旋),这就是自旋锁。 自旋等待的时间必须要有一定限度。
    自适应指的是自旋的时间不再固定,而是由前一次在同一个锁上的自旋时间及锁的拥有者的状态来决定。
  • 锁消除
    锁消除是指虚拟机即时编译器在运行时,对一些代码要求同步,但是被检测到不可能存在共享数据的锁进行消除。锁消除的主要依据来源于逃逸分析的数据支持。
  • 锁粗化
    在频繁的互斥操作导致不必要的性能损耗是,把加锁范围扩展(粗化)到整个序列的外部。
  • 轻量级锁
  • 偏向锁
    引入目的是消除数据在无竞争情况下的同步原语,进一步提高程序的运行性能。偏向锁指的就是这个锁会偏向于第一个获得它的线程,如果在接下来的执行过程中,该锁没有被其他线程获取,则持有偏向锁的线程将永远不需要再进行同步。
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/650158
推荐阅读
相关标签
  

闽ICP备14008679号