脏读就是指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。因为这个数据是还没有提交的数据,那么另外一个事务读到的这个数据是脏数据,依据脏数据所做的操作可能是不正确的。

public class Dirtyread {
    private String userName="pdz";
    private String password="12345";
    public synchronized void updateUser(String userName, String password) {
        this.userName = userName;
        try {
            Thread.currentThread().sleep(4000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        this.password = password;
        System.out.println("更新用户信息姓名为:" + userName + "密码为:" + password);
    }


    public void queryUser() {
        System.out.println("获取用户信息姓名:" + userName + "密码:" + password);
    }



    public static void main(String[] args) {
        final  Dirtyread dirtyread = new Dirtyread();

        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                dirtyread.updateUser("张三", "111111");
            }
        });
        t1.start();
        try {
            Thread.currentThread().sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        dirtyread.queryUser();
    }
}

  上述代码中我们有一个线程t1和主线程main。为了放置更新用户数据出现冲突,所以我们把updateUser方法进行了同步。当程序运行后,结果:

获取用户信息姓名:张三密码:12345 更新用户信息姓名为:张三密码为:111111

我们获取的信息并不是完全修改后的信息。而是密码还是原来的密码,而姓名却是修改后的密码。这就是脏读。因为对象的属性帐号和密码在更新方法和获取方法之中,我们都是资源共享。也就是说多个线程在执行不同的方法的时候,都是共享这两个属性的值。所以必须要对这两个方法都进行同步。解决方法就是queryUser方法也进行synchronizedx修饰。