zoukankan      html  css  js  c++  java
  • Java多线程中读写不一致问题

    问题:
    假设有个全局变量var初始化为0
    MyThread线程循环+1
    MyThread2线程检测到var大于10时退出循环
    问题来了,我们发现MyThread一直没有退出循环
    也就是说线程没有及时刷新内存
    解决方法:给全局变量添加 volatile关键字

    Java提供了volatile来保证可见性。当一个变量被volatile修饰后,表示着线程本地内存无效,当一个线程修改共享变量后他会立即被更新到主内存中,当其他线程读取共享变量时,它会直接从主内存中读取。

    点击查看代码
    
    abstract class ThreadMemo implements Runnable {
        private Thread t;
        protected String threadName;
    
        // public static int var = 0;
        volatile public static int var = 0; // 只需要添加volatile关键字就可以了
    
        public ThreadMemo(String name) {
            threadName = name;
            System.out.println("Creating " + threadName);
        }
    
        abstract public void run();
    
        public void start() {
            System.out.println("Starting " + threadName);
            if (t == null) {
                t = new Thread(this, threadName);
                t.start();
            }
        }
    
    }
    
    class MyThread extends ThreadMemo {
    
        MyThread(String name) {
            super(name);
        }
    
        public void run() {
            var = super.var;
            while(true) {
                var = var + 1;
                // sleep(50);
                // time.sleep(50);
                try {
                    Thread.sleep(50);
                } catch (InterruptedException e) {
                    System.out.println("Thread " + threadName + " interrupted.");
                }
                // System.out.println("mythread 1 var: " + var);
            }
            
        }
    }
    
    class MyThread2 extends ThreadMemo {
    
        MyThread2(String name) {
            super(name);
        }
    
        public void run() {
            var = super.var;
            while(true) {
                if(var < 10) {
                    // try {
                    //     Thread.sleep(1);
                    // } catch (InterruptedException e) {
                    //     System.out.println("Thread " + threadName + " interrupted.");
                    // }
                    // Object o = new Object();
    
                    continue;
                } 
                System.out.println("mythread2 var = " + var);
                break;
            }
        }
    }
    
    
    
    public class Test2 {
        // public static int var = 0;
        public static void main(String[] args) {
            ThreadMemo t1 = new MyThread("Thread-1");
            ThreadMemo t2 = new MyThread2("Thread-2");
    
            Thread a = new Thread(t1);
            Thread b = new Thread(t2);
            a.start();
            b.start();
        }
    }
    

    然后我们发现,给读线程的循环中添加一些语句,循环就能退出了
    V2EX上发现相同的问题 Java 多线程并发,线程什么时候会刷新 "工作内存"

    据说是遇到IO阻塞才会刷新内存

    个性签名:时间会解决一切
  • 相关阅读:
    CCF201503-1 图像旋转(100分)
    CCF201509-1 数列分段(100分)
    CCF201509-1 数列分段(100分)
    JSP---使用checkbox实现多项删除
    JS---checkbox实现全选
    JSP---jsp页面获取物理路径
    JSP---根据值让某一Radio处于选中状态
    JSP---Myeclipse8.5使用Sql server数据库
    JSP---JSP学习笔记
    VS---解决VS2008专业版试用90天限制的方法
  • 原文地址:https://www.cnblogs.com/lfri/p/15616108.html
Copyright © 2011-2022 走看看