volatile功能与原理

功能:

volatile提供了稍弱的同步机制。被volatile修饰的变量可确保将变量的更新及时通知到其他线程。

编译器不会针对volatile修改的变量与其他变量内存重排序。

valatile不会缓存到寄存器。

访问volatile不会执行加锁操作。

使用

volatile最亮眼的是它的可见性。

从内存可见性角度看:读取volatile相当于进入同步代码、写入volatile变量相当于退出同步代码区

volatile boolean asleep;
while(!asleep)
    ...

这个是volatile的典型应用模式。

volatile只是确保变量的可见性,不足以操作的原子性,例如volatile int i=0; i++;

同步机制既可以确保共享变量的可见性、也可以确保原子性

volatile使用情形条件:

1、对变量写入操作不依赖当前变量的值,或确保只有单个线程操作变量

2、该变量不与其他状态变量一起纳入不变性条件

3、访问变量时不需要加锁。

原理

volatile修饰的变量在操作之前会引发缓存锁定:

1、将当前处理器缓存回写到系统的内存中

2、回写内存导致其他CPU里的缓存无效。

缓存锁定确保缓存一致性,会阻止同时修改有两个以上的cpu缓存的内存数据。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我知道了。首先我需要解释一下 synchronized 关键字、volatile、ReentrantLock 类与阻塞队列 LinkedBlockingQueue<E> 的概念。 synchronized 关键字是 Java 中用于实现同步的关键字,可以用来修饰代码块、方法和静态方法,用于实现线程间的同步。 volatile 是一个关键字,用于修饰变量,用于实现多线程之间的可见性,即当一个线程修改了一个 volatile 变量的值时,其他线程可以立即看到这个修改。 ReentrantLock 类是一个可重入的互斥锁,可以用来实现线程间的同步,与 synchronized 关键字相比,ReentrantLock 提供了更多的功能,如公平锁和可中断锁等。 阻塞队列 LinkedBlockingQueue<E> 是一个基于链表实现的阻塞队列,在多线程编程中可以用来实现线程间的同步。 接下来,我将使用这些同步方法实现主线程与子线程的同步,并写出实验小结。 代码如下: ``` import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.locks.ReentrantLock; public class Main { private volatile boolean flag = false; private final ReentrantLock lock = new ReentrantLock(); private final LinkedBlockingQueue<Integer> queue = new LinkedBlockingQueue<>(); public static void main(String[] args) { Main main = new Main(); main.start(); } private void start() { Thread t = new Thread(() -> { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } flag = true; lock.lock(); try { queue.put(1); } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } }); t.start(); lock.lock(); try { while (!flag) { Thread.sleep(100); } System.out.println(queue.take()); } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } } } ``` 在这个例子中,主线程和子线程都需要修改和访问共享变量 flag,因此需要使用 volatile 关键字来实现可见性。 主线程需要等待子线程修改 flag 后才能继续执行,因此可以使用 while 循环不断检查 flag 是否被修改,这里使用了 Thread.sleep(100) 来减少 CPU 的占用率。 子线程需要将一个元素加入到队列中,并通知主线程可以继续执行,因此可以使用 ReentrantLock 和 LinkedBlockingQueue 来实现线程间的同步。 实验小结: 在多线程编程中,同步是一个非常重要的概念,可以用来避免线程间的竞争和冲突。在 Java 中,可以使用 synchronized 关键字、volatile、ReentrantLock 类和阻塞队列 LinkedBlockingQueue<E> 等方法来实现线程间的同步。在实际编程中,应根据情况选择不同的同步方法,以保证程序的正确性和效率。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值