• 多线程(三)~多线程中数据的可见性-volatile关键字


    我们先来看一段代码:
    ①.线程类,用全局布尔值控制线程是否结束,每隔1s打印一次当前线程的信息
    1. package com.multiThread.thread;
    2. publicclassPrintStringimplementsRunnable{
    3. privateboolean isContinuePrint =true;
    4. @Override
    5. publicvoid run(){
    6. while(isContinuePrint){
    7. try{
    8. System.out.println("current threadId is "+Thread.currentThread().getId()+",threadName is"+Thread.currentThread().getName()+",threadPriority "+Thread.currentThread().getPriority());
    9. Thread.sleep(1000);
    10. }catch(InterruptedException e){
    11. e.printStackTrace();
    12. }
    13. }
    14. System.out.println("Thread is stop!");
    15. }
    16. publicboolean isContinuePrint(){
    17. return isContinuePrint;
    18. }
    19. publicvoid setContinuePrint(boolean isContinuePrint){
    20. this.isContinuePrint = isContinuePrint;
    21. }
    22. }
    ②.测试类
    1. package com.multiThread.test.common;
    2. import com.multiThread.thread.PrintString;
    3. publicclassVolatileTest{
    4. publicstaticvoid main(String[] args){
    5. PrintString printString =newPrintString();
    6. Thread t =newThread(printString);
    7. t.start();
    8. try{
    9. Thread.sleep(2000);
    10. printString.setContinuePrint(false);
    11. }catch(InterruptedException e){
    12. e.printStackTrace();
    13. }
    14. }
    15. }
    打印结果:
    1. current threadId is 8,threadName isThread-0,threadPriority 5
    2. current threadId is 8,threadName isThread-0,threadPriority 5
    3. Thread is stop
     
    以上这段程序在我本地的eclipse上运行完全没有问题,但是一段以服务器端的参数来运行则会出现问题。
    我们修改一下eclipse的运行方式,带上参数-server来运行这段代码,擦,运行结果还是这样,又没成功,我命名是win7+jdk64位啊。
    先不管了,按照书上说的,这块停不下来。那为什么停不下来呢?因为服务器为了兼顾性能直接从当前线程的工作内存中获取的值,没有从主内存中取。而main函数里的操作是把主内存的数据给更新了,听起来类似于程序的读缓存没查库的操作。
     
    解决的方式就是为变量此变量加上volatile关键字来修饰。volatile关键字修饰的变量会强制从主内存中读取数据,保证数据的可见性。
    此关键字的应用场景为:多线程中可以感知实例变量被更改了。并且可以获得最新的值使用,也就是多线程读取共享变量时可以获得最新的值使用
    1. privatevolatileboolean isContinuePrint =true;
     
    附带volatile关键字的工作图:
     
    当然,此处也可以采用synchronize的方式来处理,不过synchronize和volatile关键字的作用是不同的。
    这里要注重强调一下二者的区别和作用:
    volatile:强制从主内存读取数据,保证数据的可见性。volatile的操作不是原子性的。
    synchronize:同步操作,保证一次监视对象一次只有一个线程去处理。synchronize本身也可以保证数据的可见性,同时更重要的是用来保证数据的同步性。
     
    多线程这块的处理都是围绕着数据的同步性、可见性和原子性来操作的,记住这个原则就OK。
    下一章我们来看一下和原子性有关的操作。
     
    用一张图来描述变量在内存中的工作流程:
     
     





  • 相关阅读:
    CuteWebUI AJAX Uploader上载控件介绍
    Trident的发展
    jQuery定义类及扩展
    margintop和paddongtop IE
    自己实现的一个简单的相册效果
    Firefox 浮动层背景图不能自动平铺(困惑)
    jQuery对象和DOM对象
    jQuery之Ajax之一
    position
    DOM基础心得
  • 原文地址:https://www.cnblogs.com/douJiangYouTiao888/p/6473805.html
Copyright © 2020-2023  润新知