• 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);
        }
    
    }

    运行结果:

  • 相关阅读:
    [LintCode] Valid Palindrome 验证回文字符串
    [LeetCode] 378. Kth Smallest Element in a Sorted Matrix 有序矩阵中第K小的元素
    [LintCode] Integer to Roman 整数转化成罗马数字
    [LintCode] Roman to Integer 罗马数字转化成整数
    [LintCode] Scramble String 爬行字符串
    [LintCode] Count and Say 计数和读法
    [LintCode] Simplify Path 简化路径
    [LintCode] Length of Last Word 求末尾单词的长度
    [LintCode] Valid Parentheses 验证括号
    [LeetCode] 377. Combination Sum IV 组合之和之四
  • 原文地址:https://www.cnblogs.com/AK47Sonic/p/7713504.html
Copyright © 2020-2023  润新知