多线程原子性

原子性是指在一次操作或多次操作中,要么所有的操作全部都得到了执行并不会受到任何因素的干扰而中断,要么所有的操作都不执行,多个操作是一个不可分割的整体

volatile关键字

因为堆内存是唯一的而每一个线程都有自己的线程栈

每一个线程栈在使用堆内存里面的变量时都会拷贝到变量的副本中

在线程中每一次使用是从变量副本中获取的

volatile关键字是强制线程每次使用时都会看一下共享区的最新值

synchronized

synchronized锁解决流程

1线程获得锁

2清空变量副本

3拷贝共享变量最新的值到变量副本中

4执行代码

4将修改后的变量副本的值赋值给共享数据

6释放锁

AtomicInteger

自增(++)不是一个原子性的操作,所以JDK5之后提供了AtomicInteger

//        初始化一个默认值为0的原子型Integer
        AtomicInteger ac1 = new AtomicInteger();
 //        初始化一个指定值的的原子型Integer,此处指定值为10
        AtomicInteger ac2 = new AtomicInteger(10);
        // int get(): 获取值
        int i = ac2.get();
        // int getAndIncrement(): 以原子方式将当前值加1,注意,这里返回的是自增前的值。
        int andIncrement = ac1.getAndIncrement();
        // int incrementAndGet(): 以原子方式将当前值加1,注意,这里返回的是自增后的值。
        int i1 = ac2.incrementAndGet();
        // int addAndGet(int data): 以原子方式将参数与对象中的值相加,并返回结果。
        int i2 = ac2.addAndGet(20);
        // int getAndSet(int value): 以原子方式设置为newValue的值,并返回旧值。
        int andSet = ac2.getAndSet(10);

AtomicInteger原理

AtomicInteger原理是:自旋锁+CAS算法

CAS算法:

有三个操作的数:内存值,旧的值A,要修改的值B

当旧的值A==内存值,修改成功,将内存值改为新的值B

当旧的值A!=内存值,修改失败,不做任何操作,并重新获取现在的最新值

重新获取最新值的动作就是自旋

悲观锁和乐观锁

悲观锁:每次操作共享数据前都会上锁

乐观锁:修改共享数据时会检查数据是否被修改,如被修改就再次获取新值,没被修改直接修改共享数据的值

synchronized和CAS的区别:

        synchronized是悲观锁

        CAS是乐观锁

HashTable

在集合类中HashMap虽然常用但他是线程不安全的集合,多线程环境下可能会出现问题。为保证数据安全性可以使用HashTable,但HashTable操作数据的时候会将整张表锁起来,所以效率较低

ConcurrentHashMap

JDK5后提供的此类,但在JDK7和JDK8的两个版本中的底层原理不一样

底层原理:

空参构造创建ConcurrentHashMap如果什么都不操作,在第一次添加元素时会创建哈希表

计算当前元素应存入的索引

如果该索引位置为null,则利用cas算法将本节点添加到数组中

如果该索引为不为null,则利用volatile关键字获取当前位置最新地址值,挂载添加变成链表

当链表长度>=8时会自动转换为红黑树,以链表或红黑树头节点为锁对象,配合悲观锁保证多线程操作集合数据时的安全性

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: JUC是Java.util.concurrent的缩写,提供了许多并发编程的工具类,其中就包括了解决多线程原子性问题的类。 在JUC中,提供了多个原子类,例如AtomicIntegerAtomicLong等,这些类可以保证对其操作的原子性,也就是说,对它们进行读写操作时,不会出现数据不一致的情况。 下面是一个使用AtomicInteger解决多线程原子性问题的示例代码: ```java import java.util.concurrent.atomic.AtomicInteger; public class AtomicExample { private AtomicInteger count = new AtomicInteger(0); public void increment() { count.incrementAndGet(); } public int getCount() { return count.get(); } } ``` 在这个示例中,count是一个AtomicInteger类型的变量,它的incrementAndGet()方法可以保证对它进行操作的原子性,即使有多个线程同时对它进行操作,也不会出现数据不一致的情况。 因此,使用JUC提供的原子类可以很方便地解决多线程原子性问题。 ### 回答2: JUC(Java Util Concurrent)是Java并发实用工具包,在解决多线程原子性问题上提供了丰富的解决方案。下面是JUC中常用的两种解决方案,以代码示例的形式展示。 1. synchronized关键字 synchronized关键字是Java中最基本的同步机制,通过给关键代码块或方法加锁,确保同一时间只能有一个线程执行该代码块或方法,以实现原子性操作。 ```java public class Counter { private int count; public synchronized void increment() { count++; } } ``` 2. AtomicAtomic类是JUC中提供的一组原子操作类,它们利用底层的CAS(Compare and Swap)机制实现原子性操作。CAS机制通过比较内存中的值与期望值,若相等则修改为新值,若不相等则重新尝试,直至更新成功。Atomic类可实现基本类型和引用类型的原子操作。 ```java import java.util.concurrent.atomic.AtomicInteger; public class Counter { private AtomicInteger count = new AtomicInteger(0); public void increment() { count.incrementAndGet(); } } ``` 以上是JUC解决多线程原子性问题的两个常用方案。synchronized关键字通过加锁实现,而Atomic类则利用CAS机制实现,二者都能保证多线程环境下的原子性操作。根据具体的业务场景和性能要求,选择合适的方式解决多线程原子性问题。 ### 回答3: JUC(Java并发编程工具包)是Java提供的用于解决多线程并发问题的工具包,其中包含了很多用于处理线程安全的类和接口。 JUC中解决多线程原子性问题的方式主要是通过提供原子类来实现。原子类是一种可以单独访问和修改的变量类型,它们可以以原子方式执行操作,保证了操作的原子性。 下面是一个使用JUC提供的原子类AtomicInteger来解决多线程原子性问题的示例代码: ```java import java.util.concurrent.atomic.AtomicInteger; public class AtomicityExample { private static AtomicInteger counter = new AtomicInteger(0); public static void main(String[] args) throws InterruptedException { Thread thread1 = new Thread(new IncrementTask()); Thread thread2 = new Thread(new IncrementTask()); thread1.start(); thread2.start(); thread1.join(); thread2.join(); System.out.println("Counter: " + counter); } static class IncrementTask implements Runnable { @Override public void run() { for (int i = 0; i < 10000; i++) { counter.incrementAndGet(); // 使用原子方式将当前值加1 } } } } ``` 在上述示例代码中,使用AtomicInteger类来声明了一个原子变量counter。在IncrementTask任务中,每次循环通过调用incrementAndGet()方法对counter的值进行原子自增操作。 使用JUC提供的原子类可以确保多线程环境下对变量的操作是原子性的,避免了出现竞态条件等线程安全问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

念兰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值