脏读——T2106

package 对象及变量的并发访问2;

/**
 * 脏读
 *
 *   在多个线程调用同一个方法时为了避免数据出现交叉的情况,使用synchronized关键字来进行同步
 *   虽然在赋值时进行了同步,但在取值时有可能出现一些意想不到的情况,这种情况就是脏读(dirty read)
 * 发生脏读的原因是在读取实例变量的时候,此值已经被其他线程改变。
 *
 *   出现脏读是因为public void getValue()方法并不是同步的,所以可以在任意时刻调用,解决办法就是加上synchronized关键字
 *
 *   当线程A调用任何anyObject对象加入synchronized关键字的X方法时,A线程就获得了X方法所在的对象锁,但B线程可以随意调用其他
 * 非synchronized同步方法
 *   当A线程调用anyObject对象加入synchronized关键字X方法时,A线程就获得了X方法所在对象的锁,所以其他线程必须等待A线程执行
 * 完后才可以调用X方法,而B线程如果调用声明了synchronized关键字的非X方法,必须等A线程将X方法执行完,也就是将对象锁进行释放
 * 后才可以调用,这是A线程已经执行了一个完整的任务,也就是说usernsme和password这两个实例已经同时被赋值,不存在脏读的基本环境。
 *
 *   多线程执行同一个业务对象中的不同同步方法时,是按顺序同步的方式调用的。
 *   脏读前一定会出现不同线程一起去写实例变量的情况,这就是不同线程“争抢”实例变量的结果。
 */
 class PublicVarT216{
     public String unsername="A";
     public String password="AA";
     synchronized public void setValue(String unsername,String password){
         try {
             this.unsername=unsername;
                Thread.sleep(5000);
                this.password=password;

             System.out.println("setValue method thread name="+Thread.currentThread().getName()+
                     "  username="+unsername+"  password="+password);

         } catch (InterruptedException e) {
             e.printStackTrace();
         }
     }
   synchronized   public void getValue(){
         System.out.println("getValue method thread name="+Thread.currentThread().getName()+
                 "  username="+unsername+"  password="+password);
     }
}

class MyThreadAT216 extends Thread{
     private PublicVarT216 publicVarT216;
     public MyThreadAT216(PublicVarT216 publicVarT216){
         super();
         this.publicVarT216=publicVarT216;
     }

    @Override
    public void run() {
        super.run();
        publicVarT216.setValue("B","BB");
    }
}
class RunT216{
     public RunT216(){
         try {
             PublicVarT216 publicVarT216=new PublicVarT216();
             MyThreadAT216 at216=new MyThreadAT216(publicVarT216);
             at216.start();

             //输出结果受睡眠时间影响
             Thread.sleep(200);

             publicVarT216.getValue();
         } catch (InterruptedException e) {
             e.printStackTrace();
         }
     }
}
public class T2106 {

    public static void main(String[] args) {
        RunT216 runT216=new RunT216();
    }
}

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值