zoukankan      html  css  js  c++  java
  • 脏读

    脏读:对于对象的同步和异步的方法,我们在设计自己的程序的时候,一定要考虑问题的整体,不然就会出现数据不一致的错误,很经典的错误就是脏读(dirtyread)

    我们首先通过一个小demo来认识一下脏读:

    public class DirtyRead {
    private String username = "zjkj";
    private String password = "123";

    public synchronized void setValue(String username, String password) {
    this.username = username;
    try {
    Thread.sleep(2000);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    this.password = password;
    System.out.println("setValue最终结果:username = " + username +
    " , password = " + password);
    }

    public void getValue() {
    System.out.println("getValue最终结果:username = " + username +
    " , password = " + password);
    }

    public static void main(String[] args) throws InterruptedException {
    final DirtyRead dr = new DirtyRead();
    Thread t1 = new Thread(new Runnable() {
    @Override
    public void run() {
    dr.setValue("z3", "456");
    }
    });
    t1.start();
    Thread.sleep(1000);
    dr.getValue();
    }
    }


    对于这段代码,其实我们想要的结果是:

    setValue最终结果:username = z3 , password = 456
    getValue最终结果:username = z3, password = 456

    事实上,运行后的结果是:

    getValue最终结果:username = z3 , password = 123
    setValue最终结果:username = z3 , password = 456

    这是因为t1线程运行到setValue方法中,sleep了2秒中,此时,username已经被赋值,然后在主线程中,由于只sleep了1秒中,此时开始执行getValue方法,所以先打印的会是getValue,username = z3 , password = 123,这种就是存在线程安全的,也就是所谓的脏读。

    为了解决这个问题,可以在getValue方法上也使用synchronized进行修饰,这里面,两次调用方法的是同一个对象,这样运行后的结果就是我们想要的结果。synchronized的定义中有提到过,当一个线程访问object的一个synchronized(this)同步代码块时,其他线程对object中所有其它synchronized(this)同步代码块的访问将被阻塞。从而保证线程是安全的,第一次出现错误的结果,是因为当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该object中的非synchronized(this)同步代码块。

    总结:在我们对一个对象的方法加锁的时候,需要考虑业务的整体性,即为setValue/getValue方法同时加锁synchronized同步关键字,保证业务(service)的原子性,不然会出现业务错误(也从侧面保证业务的一致性)。

  • 相关阅读:
    16平衡树
    15二叉检索树
    11用户权限
    10触发器
    8函数
    8存储过程
    linux下如何进入单用户模式
    RHEL6.4 字符模式下安装图形界面图文教程
    杂记
    Java内存管理(一):深入Java内存区域
  • 原文地址:https://www.cnblogs.com/shmilyToHu/p/6382608.html
Copyright © 2011-2022 走看看