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

}

运行结果:

 

posted @ 2017-10-23 07:18  AK47Sonic  阅读(380)  评论(0编辑  收藏  举报