zoukankan      html  css  js  c++  java
  • Java多线程-volatile关键字

    关键字 volatile 的作用主要有两个:

    1)使变量线程间可见;

    2)禁止指令重排序(CPU和编译器为了提升程序的执行效率, 通常会按照一定的规则对指令进行优化, 如果两条指令互不依赖, 则有可能它们执行的顺序并不是源代码编写的顺序)。

     因私有堆栈和公共堆栈值不同导致的死循环

    示例:

    public class VolatileTest1 {
        public static void main(String[] args) throws InterruptedException {
            RunThread thread = new RunThread();
            thread.start();
            Thread.sleep(1000);
            thread.setRunning(false);
            System.out.println("已经赋值为 false");
        }
    
        static class RunThread extends Thread {
            private boolean isRunning = true;
            public boolean isRunning() {
                return isRunning;
            }
    
            public void setRunning(boolean isRunning) {
                this.isRunning = isRunning;
            }
    
            @Override
            public void run() {
                System.out.println("进入run了");
                while (isRunning == true) {
    
                }
                System.out.println("线程被停止了");
            }
        }
    }

    运行结果:

     可以看到,结果进入死循环了。原因是 thread 线程一直在拿它自己线程的私有栈中的 isRunning 的值来判断,而 threa.setRunning(false) 虽然被执行,但是更新的却是公共堆栈中的 isRunning。

    解决方案,就是为 isRunning 加上 valotile 修饰,让 thread 线程每次拿 isRunning 的值,都是公共堆栈中拿取

    线程私有堆栈

     volatile变量读取公共内存

    变量在内存中的工作过程

    synchornized 和 volatile 对比

    1)关键字volatile 是线程同步的轻量级实现,所以 volatile 性能比 synchronized 要好,并且 volatile 只能修饰变量,synchronized 可以修饰方法 和 代码块

    2)多线程访问 volatile 不会发生阻塞,而 synchronized 会出现阻塞

    3)volatile 保证数据的可见性,但不能保证数据的原子性; 而 synchronized 保证了原子性,也可以间接保证可见性

  • 相关阅读:
    [转] 股票基础知识
    [原] combobox如何让用户不能输入只能从下拉列表里面选择
    【原】2个面试问题(与同事李将的交流)
    [转] 纯代码取得本机IP地址
    [转] 关于硬盘修复以及低级格式化的一些文章
    [转] 130道C#面试题
    初学Sockets编程(四) 发送和接收数据
    利用Beyond Compare比较文件
    第三日:SimuLink之后是Stateflow
    简单的RPC编程实践——HelloWorld的实现
  • 原文地址:https://www.cnblogs.com/lkc9/p/12508113.html
Copyright © 2011-2022 走看看