Java线程安全以及线程安全的实现方式和内存模型(JMM)(2)

简介: Java线程安全以及线程安全的实现方式和内存模型(JMM)(2)

四、java中的线程安全等级

不可变:

可以是基本类型的final;可以是final对象,但对象的行为不会对其状态产生任何影响,比如String的subString就是new一个String对象各种Number类型如BigInteger和BigDecimal等大数据类型都是不可变的,但是同为Number子类型的AtomicInteger和AtomicLong则并非不可变。原因与它里面状态对象是unsafe对象有关,所做的操作都是CAS操作,可以保证原子性。


绝对线程安全:

不管运行时环境如何,调用者都不需要任何额外的同步措施。


相对线程安全:

这是我们通常意义上的线程安全。需要保证对象单独的操作是线程安全的。比如Vector,HashTable,synchronizedCollection包装集合等。


线程兼容:

对象本身不是线程安全的,但可以通过同步手段实现。一般我们说的不是线程安全的,绝大多数是指这个。比如ArrayList,HashMap等。


线程对立:

不管调用端是否采用了同步的措施,都无法在并发中使用的代码。

五、线程安全的实现方式

要实现线程安全一般至少需要两个特性:原子性和可见性


1)使用synchronize:它本具有原子性和可见性的,所以如果使用了synchronize修饰的操作,那么就自带了可见性,synchronized使用悲观锁来实现线程安全


2)使用原子类代替基本数据类型,原子类是使用乐观锁来实现线程安全,多线程环境下执行a++,可以使用AtomicInteger类incrementAndGet()方法实现,同样是使用了volatile来保证可见性;使用Unsafe调用native本地方法CAS,CAS采用总线加锁或缓存加锁方式来保证原子性。


3 ) 使用volatile关键字,volatile不一定就有原子性,比如用volatile修饰的变量进行++或者--操作(num++),我们需要让volatile修饰的变量需要具有原子性,那么我们一般可以设置在boolean类型变量上,如下

volatile boolean tag = true;
线程1 while(tag){};
线程2 while(tag){};

如果有变量自增或者自减,我们可以使用原子类(AtomicInteger)


4)使用ThreadLocal对各个线程进行隔离


可以参考我的这篇博客 :Java之ThreaLocal


5)我们还可以用其他的锁,比如重入锁(ReentrantLock) 保证线程安全


6)我们还可以用 临界区、互斥量、信号量 保证线程安全



参考文献:


https://developer.51cto.com/art/201910/605093.htm


https://www.open-open.com/lib/view/open1459412319988.html


https://www.iteye.com/blog/smallbug-vip-2275743


https://juejin.im/post/5c936018f265da60ec281bcb


https://blog.csdn.net/jingzi123456789/article/details/78004074

相关文章
|
13天前
|
缓存 安全 Java
Java并发编程进阶:深入理解Java内存模型
Java并发编程进阶:深入理解Java内存模型
27 0
|
2天前
|
安全 Java API
【性能与安全的双重飞跃】JDK 22外部函数与内存API:JNI的继任者,引领Java新潮流!
【9月更文挑战第7天】JDK 22外部函数与内存API的发布,标志着Java在性能与安全性方面实现了双重飞跃。作为JNI的继任者,这一新特性不仅简化了Java与本地代码的交互过程,还提升了程序的性能和安全性。我们有理由相信,在外部函数与内存API的引领下,Java将开启一个全新的编程时代,为开发者们带来更加高效、更加安全的编程体验。让我们共同期待Java在未来的辉煌成就!
24 11
|
3天前
|
安全 Java API
【本地与Java无缝对接】JDK 22外部函数和内存API:JNI终结者,性能与安全双提升!
【9月更文挑战第6天】JDK 22的外部函数和内存API无疑是Java编程语言发展史上的一个重要里程碑。它不仅解决了JNI的诸多局限和挑战,还为Java与本地代码的互操作提供了更加高效、安全和简洁的解决方案。随着FFM API的逐渐成熟和完善,我们有理由相信,Java将在更多领域展现出其强大的生命力和竞争力。让我们共同期待Java编程新纪元的到来!
24 11
|
12天前
|
Java 编译器 开发者
深入浅出Java内存模型
【8月更文挑战第28天】Java内存模型(JMM)是理解Java并发编程不可或缺的一环。本文通过浅显易懂的方式,带你一探JMM的奥秘,从基本概念到工作原理,再到实际代码示例,逐步揭开Java内存模型的神秘面纱。无论你是初学者还是有一定经验的开发者,这篇文章都将为你提供新的视角和深入的理解。
|
13天前
|
监控 安全 Java
Java多线程调试技巧:如何定位和解决线程安全问题
Java多线程调试技巧:如何定位和解决线程安全问题
65 2
|
13天前
|
存储 缓存 Java
Java内存模型(JMM)
Java内存模型(JMM)是一个抽象概念,用于规范程序中各种变量(实例字段、静态字段及数组元素)的访问方式,确保不同Java虚拟机(JVM)上的并发程序结果一致可靠。JMM定义了主存储器(所有线程共享)与工作存储器(线程私有)的概念,线程间通过主存储器进行通信。JMM具备三大特性:原子性(确保基本读写操作的不可分割)、可见性(确保一个线程对共享变量的修改对其他线程可见)、有序性(防止指令被处理器或编译器重排序影响程序逻辑)。通过这些特性,JMM解决了多线程环境下的数据一致性问题。
|
16天前
|
安全 Java 编译器
深入Java内存模型:解锁并发编程的秘密
【8月更文挑战第24天】在Java的世界,内存模型是支撑并发编程的基石。本文将深入浅出地探讨Java内存模型(JMM)的核心概念、工作原理及其对高效并发策略的影响。我们将通过实际代码示例,揭示如何利用JMM来设计高性能的并发应用,并避免常见的并发陷阱。无论你是Java新手还是资深开发者,这篇文章都将为你打开并发编程的新视角。
30 2
|
9天前
|
前端开发 开发者 安全
JSF支付功能大揭秘:探索如何在Java世界中实现安全无缝的在线支付体验
【8月更文挑战第31天】在电子商务和在线交易日益普及的今天,实现在线支付功能已成为许多Web应用的必备需求。JavaServer Faces (JSF) 作为一种流行的Java Web框架,提供了丰富的组件和工具来构建用户界面,包括与支付网关集成以实现在线支付。支付网关是处理信用卡和借记卡支付的系统,在商家和银行之间起到桥梁作用。本文将探讨如何使用JSF与支付网关集成,以及实现在线支付功能时需要考虑的关键点
21 0
|
13天前
|
存储 监控 Java
Java多线程优化:提高线程池性能的技巧与实践
Java多线程优化:提高线程池性能的技巧与实践
41 1
|
5天前
|
存储 Ubuntu Linux
C语言 多线程编程(1) 初识线程和条件变量
本文档详细介绍了多线程的概念、相关命令及线程的操作方法。首先解释了线程的定义及其与进程的关系,接着对比了线程与进程的区别。随后介绍了如何在 Linux 系统中使用 `pidstat`、`top` 和 `ps` 命令查看线程信息。文档还探讨了多进程和多线程模式各自的优缺点及适用场景,并详细讲解了如何使用 POSIX 线程库创建、退出、等待和取消线程。此外,还介绍了线程分离的概念和方法,并提供了多个示例代码帮助理解。最后,深入探讨了线程间的通讯机制、互斥锁和条件变量的使用,通过具体示例展示了如何实现生产者与消费者的同步模型。
下一篇
DDNS