• Java 学习笔记之 线程脏读


    线程脏读:

    发生脏读的情况是在读取实例变量时,值已经被其他线程更改过了。

    public class DirtyReadVar {
        public String username = "A";
        public String password = "AA";
        synchronized public void setValue(String username, String password) {
            try {
                this.username = username;
                Thread.sleep(5000);
                this.password = password;
                System.out.println("setValue method thread name = " + Thread.currentThread().getName() + " username = " + username + " password = " + password);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    
        public void getValue(){
            System.out.println("getValue method thread name = " + Thread.currentThread().getName() + " username = " + username + " password = " + password);
        }
    
    }
    
    public class DirtyReadVarThread extends Thread {
        private DirtyReadVar dirtyReadVar;
    
        public DirtyReadVarThread(DirtyReadVar dirtyReadVar) {
            this.dirtyReadVar = dirtyReadVar;
        }
    
        @Override
        public void run() {
            super.run();
            dirtyReadVar.setValue("B", "BB");
        }
    }
    
    public class ThreadRunMain {
        public static void main(String[] args) {
            testDirtyReadVarThread();
        }
    
        public static void testDirtyReadVarThread(){
            try {
                DirtyReadVar dirtyReadVar = new DirtyReadVar();
                DirtyReadVarThread thread = new DirtyReadVarThread(dirtyReadVar);
                thread.start();
                Thread.sleep(200);
                dirtyReadVar.getValue();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    运行结果:

    出现脏读是因为getValue()方法没有同步,可以在任意时候进行调用。解决方法就是加上synchronized关键字:

    public class DirtyReadVar {
        public String username = "A";
        public String password = "AA";
        synchronized public void setValue(String username, String password) {
            try {
                this.username = username;
                Thread.sleep(5000);
                this.password = password;
                System.out.println("setValue method thread name = " + Thread.currentThread().getName() + " username = " + username + " password = " + password);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    
        synchronized public void getValue(){
            System.out.println("getValue method thread name = " + Thread.currentThread().getName() + " username = " + username + " password = " + password);
        }
    
    }

    运行结果:

  • 相关阅读:
    【Alpha】开发日志Day30714
    【Alpha】开发日志Day10712
    实验1
    实验2
    图深度优先搜索最短路径
    一切都结束了
    C#操作XML(读XML,写XML,更新,删除节点,与dataset结合等)
    字符串匹配
    纯数学规律题
    高精度
  • 原文地址:https://www.cnblogs.com/AK47Sonic/p/7713504.html
Copyright © 2020-2023  润新知