Java并发(4) 您所在的位置:网站首页 cas是线程安全的吗 Java并发(4)

Java并发(4)

2024-07-05 12:44| 来源: 网络整理| 查看: 265

线程安全定义:当多个线程访问某个类时,不管运行时环境采用何种调度方式或者这些进程如何交替运行,并且在主调程序中不需要额外的同步或者协同,这个类都能表示出正确的行为,那么就称这个类为线程安全的。

线程安全主要体现在三个方面,分别是原子性、可见性、有序性。 ==1==

一. 原子性 1: Atomic包

Java并发编程-无锁CAS与Unsafe类及其并发包Atomic 在Atomic包共提供了13个原子操作类,这些写原子操作类提供了一些简单高效的更新变量的方式。Atomic包里的类都是基于Unsafe类实现的包装类。这13个类主要分为

原子更新基本类型、原子更新数组、原子更新引用、原子更新属性

1. AtomicInteger原子类:基本类型

AtomicInteger 属于原子更新基本类型 AtomicInteger测试类:

package com.hust.concurrency.service.atomic; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Semaphore; import java.util.concurrent.atomic.AtomicInteger; import com.hust.concurrency.annoations.ThreadSafe; import lombok.extern.slf4j.Slf4j; /** * @Description 原子操作类 * @since 2019年1月8日 下午8:37:54 * @author LiuLiBin */ @Slf4j @ThreadSafe public class AtomicIntegerTest { //请求总数 public static int clientTotal = 1000; //同时并发执行的线程数 public static int threadTotal = 50; //测试并发 的计数值 public static AtomicInteger count = new AtomicInteger(0) ; public static void main(String[] args) throws InterruptedException { //定义线程池 ExecutorService executorService = Executors.newCachedThreadPool(); //定义信号量 ,信号量为 50 final Semaphore semaphore = new Semaphore(threadTotal); //定义计数器闭锁 ,期望所有请求请求完后统计计数结果 final CountDownLatch countDownLatch = new CountDownLatch(clientTotal); //放入请求,将请求线程全部放入线程池中 for (int i = 0; i @Override public void run() { // TODO Auto-generated method stub try { semaphore.acquire(); // 获取一个许可 add(); semaphore.release(); // 释放一个许可 } catch (Exception e) { log.error("exception", e); } countDownLatch.countDown(); // 计数器闭锁减1 } }); } //在所有线程请求执行完后 ,唤醒等待线程 ,此处涉及到countDownLatch 的实现机制 countDownLatch.await(); //关闭线程池 executorService.shutdown(); //打印计数值信息 log.info("count:{}",count.get()); } /** * 增加计数值 */ private static void add() { //以原子的方式将当前值加1,并返回加1后的值 count.incrementAndGet(); } }

在上面代码中,count.incrementAndGet()方法是基于 compareAndSet 方法实现以原子的方式将当前值加1,并返回加1后的值。下面来看下AtomicInteger 的部分源码: ==2== 在上图中,compareAndSwapInt() 方法就是java 程序中的CAS指令,虚拟机在内部对这个方法进行了特殊处理,即时编译出来的是一条与平台相关的处理器CAS指令。 ==3==

2. 原子更新数组、原子更新引用、原子更新属性

详见链接:原子操作类

3. AtomicStampReferenc:CAS的ABA问题

==4==

2: synchronized关键字

详见:深入理解Java并发之synchronized实现原理

二. 可见性

可见性是指当一个线程修改了共享变量的值,其他线程能够立即得到这个修改。volatile、synchronized 、final 修饰的变量都可以实现可见性 ==5== ==6==

三.有序性

有序性是指对于单线程的执行代码,我们总是认为代码的执行是按顺序依次执行的,这样的理解并没有毛病,毕竟对于单线程而言确实如此,但对于多线程环境,则可能出现乱序现象,因为程序编译成机器码指令后可能会出现指令重排现象,重排后的指令与原指令的顺序未必一致,要明白的是,在Java程序中,倘若在本线程内,所有操作都视为有序行为,如果是多线程环境下,一个线程中观察另外一个线程,所有操作都是无序的,前半句指的是单线程内保证串行语义执行的一致性,后半句则指指令重排现象和工作内存与主内存同步延迟现象。

参考: 深入理解Java并发之synchronized实现原理 Java并发编程-无锁CAS与Unsafe类及其并发包Atomic



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有