zoukankan      html  css  js  c++  java
  • volatile关键字

     首先创建一个MyThread类,继承Thread,有一个成员变量flag,重写run方法:

    package com.lit.thread003;
    
    public class MyThread extends Thread{
    	private  boolean flag = true ;
    	
    	public boolean isFlag() {
    		return flag;
    	}
    	public void setFlag(boolean flag) {
    		this.flag = flag;
    	}
    
    	@Override
    	public void run() {
    		System.out.println("---进入run方法---");
    		while(flag){
    			//System.out.println("我在while循环中");
    		}
    		System.out.println("---结束run方法---");
    	}
    	
    }
    

      

      然后,创建Run类,如下:

    package com.lit.thread003;
    
    public class Run {
    	public static void main(String[] args) {
    		
    		try {
    			final MyThread thread = new MyThread() ;
    			thread.start();
    			Thread.sleep(1000);
    			
    			new Thread(new Runnable() {
    				
    				@Override
    				public void run() {
    					thread.setFlag(false);
    				}
    			}).start();
    			System.out.println("set false");
    			
    		} catch (InterruptedException e) {
    			e.printStackTrace();
    		}
    	}
    }
    

      运行结果如下:

    ---进入run方法---
    set false
    

      可以看到,程序的运行结果出现了死循环,另一个线程修改了flag的值为false之后,并没有跳出循环,这是因为在执行代码thread.start()启动这个线程时,变量private boolean flag = true存在于公共堆栈以及线程的私有堆栈中。为了提高线程的运行效率,线程一直从私有堆栈中取得flag的值是true,而代码 thread.setFlag(false); 虽然被执行,但是更新的确是公共堆栈中的flag变量值false,所以程序一直是死循环的状态。

      解决公共堆栈和私有堆栈值不同可以使用关键字volatile,它的主要作用是当前线程访问flag这个变量的时候,强制性的从公共堆栈读取。

      将MyThread.java的代码更改如下:

    public class MyThread extends Thread{
    	private volatile  boolean flag = true ;
    	
    	public boolean isFlag() {
    		return flag;
    	}
    
    	public void setFlag(boolean flag) {
    		this.flag = flag;
    	}
    
    	@Override
    	public void run() {
    		System.out.println("---进入run方法---");
    		while(flag){
    			//System.out.println("我在while循环中");
    		}
    		System.out.println("---结束run方法---");
    	}
    	
    }
    

      运行Run.java  :

    ---进入run方法---
    set false
    ---结束run方法---
    

      问题解决。

      但是仍然需要注意的是volatile关键字虽然增加了实例变量在多个线程之间的可见性,但是它的缺点在于不支持原子性。

  • 相关阅读:
    面向对象的核心概念
    堆栈和托管堆 c#
    DIV绘制图形
    slideLeft DIV向左右滑动
    结构化分析
    函数
    HTML CSS 特殊字符表
    100以内的数是正整数 if的基本用法
    简单三个数比较大小 “?!”的用法
    简单计算器
  • 原文地址:https://www.cnblogs.com/dquery/p/6390739.html
Copyright © 2011-2022 走看看