• 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关键字虽然增加了实例变量在多个线程之间的可见性,但是它的缺点在于不支持原子性。

  • 相关阅读:
    Java基础学习07--内部类与常用类
    Java基础学习06--集合
    leetcode124
    Python深度学习笔记09--使用Keras建立循环神经网络
    Python深度学习笔记08--处理文本数据的常用方法
    详解DNS域名解析系统(域名、域名服务器[根、顶级、授权/权限、本地]、域名解析过程[递归与迭代])
    计算机网络之应用层概述(C/S模型与p2p模型)
    计算机网络传输层之TCP拥塞控制(慢开始与拥塞避免、快重传和快恢复)
    计算机网络传输层之TCP流量控制
    计算机网络传输层之TCP可靠传输
  • 原文地址:https://www.cnblogs.com/dquery/p/6390739.html
Copyright © 2020-2023  润新知