zoukankan      html  css  js  c++  java
  • Java多线程技术-Volatile关键字解析

    分析volatile关键字可以从这三个方面分析,什么是程序的原子性,什么是程序的可见性,什么是程序的有序性

    什么是程序的原子性

    以下语句那些是原子操作?

    public class ThreadCounter implements Runnable {
          private int count = 0;
          @Override
          public void run() {
                ++count;
    //          count++;
          }
          public static void main(String[] args) throws InterruptedException {
                ThreadCounter thread = new ThreadCounter();
                for(int i = 0; i< 10000; i++){
                      new Thread(thread).start();
                }
                Thread.sleep(1000);//确保线程执行完
                System.out.println(thread.count);
          }
    }
    View Code

    演示结果:语句一和二是非原子操作,语句三和四是原子操作 

    执行指令:javap -s -c ThreadCounter
    run方法的指令码(count++):
     
    count++这行代码分成了4个指令来执行,在多线程的情况下会不一致。

     解决方法:

    public class ThreadCounter implements Runnable {
          private int count = 0;
          @Override
          public void run() {
                synchronized (this) {
                      ++count;
                //    count++;
                }
          }
          public static void main(String[] args) throws InterruptedException {
                ThreadCounter thread = new ThreadCounter();
                for(int i = 0; i< 10000; i++){
                      new Thread(thread).start();
                }
                Thread.sleep(1000);//确保线程执行完
                System.out.println(thread.count);
          }
    }
    View Code

    什么是程序的可见性?

     

    public class VolatileExample {
          boolean v =false;
          
          private void write(){
                v =true;
          }
          
          private void read(){
                while(!v){
                }
                System.out.println("程序结束!");
          }
          
          public static void main(String[] args) throws InterruptedException {
                final VolatileExample example = new VolatileExample();
                Thread thread1 = new Thread(()->{example.read();});
                thread1.start();
                Thread.sleep(1000);
                Thread thread2 = new Thread(()->{example.write();});
                thread2.start();
          }
    }
    View Code
    演示结果:
        程序没有结束,read方法中的v没有因write方法的修改而退出循环!
    解决方法:为变量v添加volatile关键字
    public class VolatileExample {
          volatile boolean v =false;
          
          private void write(){
                v =true;
          }
          
          private void read(){
                while(!v){
                }
                System.out.println("程序结束!");
          }
          
          public static void main(String[] args) throws InterruptedException {
                final VolatileExample example = new VolatileExample();
                Thread thread1 = new Thread(()->{example.read();});
                thread1.start();
                Thread.sleep(1000);
                Thread thread2 = new Thread(()->{example.write();});
                thread2.start();
          }
    }
    View Code

    什么是程序的有序性?

     

    Volatile应用场景

     1. 状态标记量 
     
    public class ThreadTest {
          private volatile boolean isContinue = false;
          
          private class HandleThread extends Thread {
                @Override
                public void run() {
                      while (isContinue) {
                            // do something
                      }
                };
          }
    }
    View Code

    2. double check 

     

    总结:

    volatile在可见性和有序性可以起到作用,但是不能保证原子性,是一种弱同步。

    synchronized可以保证原子性,可见性,一致性,是一种强同步。

     
     
     
     
     
     
     
     
     
  • 相关阅读:
    SQL SERVER中变量的定义、赋值与使用
    框架设计总结
    Sass学习之路(5)——变量
    gulp入坑系列(4)——gulp的代码转换
    gulp入坑系列(3)——创建多个gulp.task
    Sass学习之路(4)——不同样式风格的输出方式
    Sass学习之路(3)——Sass编译
    gulp入坑系列(2)——初试JS代码合并与压缩
    gulp入坑系列(1)——安装gulp
    Sass学习之路(2)——Sass环境安装(windows版)
  • 原文地址:https://www.cnblogs.com/lostyears/p/8297130.html
Copyright © 2011-2022 走看看