java中线程安全问题有哪些,java中线程安全问题是什么,Java中线程安全问题

java中线程安全问题有哪些,java中线程安全问题是什么,Java中线程安全问题

本文主要介绍Java进程的安全性,给大家讲的很详细,对大家的学习或者工作都有一定的参考价值。有需要的朋友可以参考一下。

目录

I .线程不安全II .什么情况会导致线程不安全?三。Java中线程不安全的解决方案1 .线程不安全的易失性“轻量级”解决方案2 .同步自动锁定4 .公平锁定和不公平锁定机制5。易变和同步的区别6。同步和锁定的区别

一.线程不安全

在多线程执行环境下,程序的执行结果与预期结果不一致,称为线程不安全现象

二.那些情况导致了线程不安全?

大致分为以下五种情况:

(1)CPU抢占执行(无法解决);

(2)非原子性;

(3)编译器优化(指令重排)编译器优化可以在单线程下执行,但在多线程下优化会造成混乱;

(4)记忆的不可见性;(易变轻量级解决方案)

(5)多个线程修改了同一个变量。(方案:让线程自己操作变量来解决这个问题,但是业务场景变化,修改难度加大,不具有通用性)

三.Java中解决线程不安全的方案

1.volatile“轻量级”解决线程不安全

volatile的出现可以解决上图所示的隐形内存问题,禁止指令重排。

实现原理:工作内存中的变量操作结束后,线程的工作内存中的变量被强制删除,直到内存可见。注意事项:volatile无法解决原子性问题。volatile可以解决线程不安全的问题是错误的(说法不够严谨)。

下面两种方案锁定键码,让cpu排队执行。锁定操作的步骤如下:

1)尝试获取锁,如果是,则锁定它;否则,排队等待获取锁;2)解除锁定。

2.synchronized自动加锁

自动同步锁定和解锁是Jvm级别的解决方案。

同步使用示例:使用两个线程执行变量计数一次和一次-

在使用同步锁之前,由于非原子性问题,有两个线程正在运行,并且存在线程不安全性。通过使用synchronized关键字,解决了非原子问题,代码运行的实际结果与预期结果一致,保证了线程安全。

同步化的实施原则:

1.基于操作系统,通过互斥实现。

2.从Jvm的角度来看,实现了锁定和释放监视器锁的过程。

3.从Java语言本身来说,有一个互斥对象。锁存在于对象的对象头中。对象头中的“偏向线程ID”表示锁被线程占用。释放锁后,有偏差的线程ID消失。

互斥结构信息:

Owner表示锁的所有者;如果为null,则不使用锁;Nest表示锁被使用的次数,0表示没有被使用;此外,锁可以嵌套而不会出现死锁。

同步锁升级过程:

当没有线程访问时,它处于解锁状态。当第一个线程访问时,它从解锁状态变为偏置锁。轻量级锁(其他线程试图获取锁,并且锁处于自旋状态)重量级锁(将没有获取锁的线程放入等待队列)

3.手动锁定

Lock要求程序员手动锁定和释放锁;锁是一个接口;锁可以通过Lock的实现类ReentrantLock()创建:Lock Lock=new reentrant Lock();锁定操作lock.lock()并释放操作lock.unlock()

使用锁时需要注意的问题:

确保将锁定操作lock()放在try/finally之外。如果将lock()放在try中,将会出现两个问题:

(1)如果try的代码出现异常,此时将执行最终释放锁的操作。如果没有试锁,那是不可能的。

(2)try中发生异常后,最终释放锁,线程状态的异常会覆盖try中的业务异常,增加了故障排除的成本。

把lock()放在try的第一句就可以解决这个问题。

通过对比发现,业务异常不会被线程状态异常覆盖,方便故障排除!

四.公平锁与非公平锁机制

公平锁定线程按顺序执行;不公平锁没有顺序,执行效率更高;Java中默认的锁策略是不公平锁机制同步锁机制:采用不公平锁机制:默认采用不公平锁机制,但可以显式声明为公平锁。例如,创建锁对象时,在构造方法中传递true:lock lock=new reentrant lock(true)。

五.volatile和synchronized的区别

Volatile可以解决内存不可见性问题,禁止指令重排序,但不能解决非原子性问题。

Synchronized可以解决大部分线程的非安全性问题,保证关键代码排队执行,只要锁只有一个线程拥有,就可以解决非原子性问题。

六.synchronized和Lock的区别

1 .同步自动上锁和开锁,而锁需要手动上锁和开锁;

2.synchronized是Jvm级别的实现,Lock是Java语言级别的实现;

3.适用范围不同:synchronized可以修饰代码块(锁定任意对象)、静态方法(锁定当前类)和普通方法(锁定当前实例对象);Lock只能修饰代码块;

4.synchronized只有不公平的锁定策略;Lock默认采用不公平锁机制,但可以声明为公平锁。

5.锁更灵活(例如:tryLock)

这就是这篇关于Java线程安全性的文章。有关Java线程安全性的更多信息,请搜索我们以前的文章或继续浏览下面的相关文章。希望你以后能支持我们!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: