线程脏读:
发生脏读的情况是在读取实例变量时,值已经被其他线程更改过了。
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); } }
运行结果: