• java volatile关键字


    volatile关键字的主要作用是使变量在多个线程间可见。

     关键字volatile的作用是强制从公共堆栈中取得变量的值,而不是从线程私有数据栈中取得变量的值。

    1、关键字volatile与死循环:

    package com.test;
    
    public class PringString {
        private boolean isContinuePrint = true;
    
        public boolean isContinuePrint() {
            return isContinuePrint;
        }
    
        public void setContinuePrint(boolean isContinuePrint) {
            this.isContinuePrint = isContinuePrint;
        }
        
        public void printStringMethod() {
            try {
                while (isContinuePrint == true) {
                    System.out.println("run printStringMethod");
                    Thread.sleep(1000);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    package com.test;
    
    public class Run {
        
        public static void main(String[] args) {
            
            PringString print = new PringString();
            print.printStringMethod();
            System.out.println("我要停止它");
            print.setContinuePrint(false);
        }
    }
    运行结果:
    run printStringMethod
    run printStringMethod
    run printStringMethod
    run printStringMethod

    程序开始运行后,根本停不下来。因为main线程一直在处理while循环,导致程序不能继续执行后边的代码。解决的办法当然是多线程技术。

    修改PringString.java:

    package com.test;
    
    public class PringString extends Thread {
        volatile private boolean isContinuePrint = true;
    
        public boolean isContinuePrint() {
            return isContinuePrint;
        }
    
        public void setContinuePrint(boolean isContinuePrint) {
            this.isContinuePrint = isContinuePrint;
        }
        
        @Override
        public void run() {
            try {
                System.out.println("进入run了");
                while (isContinuePrint == true) {
                    System.out.println("run printStringMethod");
                    Thread.sleep(1000);
                }
                System.out.println("线程被停止了");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        
    }
    package com.test;
    
    public class Run {
        
        public static void main(String[] args) {
            
            try {
                PringString print = new PringString();
                print.start();
                Thread.sleep(1000);
                print.setContinuePrint(false);
                System.out.println("已经赋值为false");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    运行结果:
    进入run了
    run printStringMethod
    run printStringMethod
    已经赋值为false
    线程被停止了

    总结:

    使用volatile关键字增加了实例变量在多个线程之间的可见性。但volatile关键字最致命的缺点是不支持原子性。

    下面是关键字synchronized和volatile进行一下比较:

    1. 关键字volatile是线程同步的轻量级实现,所以性能要比synchronized要好。并且volatile只能修饰于变量,而synchronized可以修饰方法,以及代码块。
    2. 多线程访问volatile不会发生阻塞,而synchronized会发生阻塞。
    3. volatile能保证数据的可见性,但不能保证原子性;而synchronized可以保证原子性,也可以间接保证可见性。因为它会将私有内存和公有内存中的数据做同步。
    4. volatile解决的是多个线程之间的可见性,而synchronized解决的是多线程之间的同步性.

    关键字volatile主要使用场合是多个线程中可以感知实例变量被更改了,并且可以获得最新的使用值,此关键字提示线程每次从共享内存中读取变量,而不是从私有内存中读取,这样就保证了同步数据的可见性,但需要注意的是:如果修改实例变量中的数据,比如i++,就是i=i+1则这样的操作其实并不是一个原子操作,也就是非线程安全的。

  • 相关阅读:
    rsa~对接第三方rsa问题排查
    rancher~升级v2.6.3之后业务集群无法连rancher的解决方法
    springboot~@ConditionalOnMissingBean一切为了可扩展性
    算法~如何将整数按着类型分段
    Xtrabackup 8.0.x关于MySQL的版本支持的浅析
    Postfix发送邮件时报错“libmysqlclient.so.18: cannot open shared object file: No such file or directory”
    Java单元测试Junit5入门实战
    ASP.NET Core 6框架揭秘实例演示版[持续更新中…]
    maven的下载、安装、配置教程
    Docker + Jenkins + Gitlab + Pytest + Allure 接口自动化测试之持续集成实战终极教程
  • 原文地址:https://www.cnblogs.com/gouge/p/9118251.html
Copyright © 2020-2023  润新知