多线程之脏读 代码示例及处理
Posted IT编程之路
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多线程之脏读 代码示例及处理相关的知识,希望对你有一定的参考价值。
多线程调用同一个方法时,为了避免数据出现交叉的情况,使用synchronized关键字进行同步。虽然在赋值时进行了同步,但是在取值时有可能出现一些意想不到的意外,这种情况就是脏读。发生脏读的情况是在读取实例变量时,此值已经被其他线程更改过了。
创建程序模拟一下:publicVar.java类
线程类ThreadA.java
测试类Test.java
结果
在运行结果上看没有出现我们想要的结果username=b password=bb的数据,出现的时username=b password=aa数据,读到了为改变完成的数据这就是脏读。出现的原因时getValue()方法不是同步的,所以可以在任意时候进行调用。
解决的方法时加上synchronized关键字,代码修改如下:
运行结果:
运行种可以看出setValue()和getValue()方法是依次执行的,这个例子我们知道脏读可以通过synchronized关键字解决,也要知道多线程的synchronized关键字的以下特性和知识:
当线程A调用method对象加上sysnchronized关键字的X方法时,线程A就获得了X方法锁,更准确地讲,是获得了对象的锁,所以其他线程必须等线程A执行完毕才可以调用X方法,但是其他线程可以随意调用method对象中其他的非synchronized方法。
当线程A调用method对象加上synchonized关键字的X方法时,线程A就获得了X方法所在对象的锁,所以其他线程必须等线程A执行完毕才可以调用X方法,而其他线程调用method对象中其他声明了synchronized关键字的方法时,也必须等线程A执行完X方法,也就是放弃对象锁后才可以调用。这时线程A已经执行一个完成的任务,username和password两个实例变量同时被赋值,不存在脏读的基本环境。
脏读一定会出现操实例变量的情况下,这就是不同线程“争抢”实例变量的结果。
大家在学习过程中遇到过什么问题也欢迎在留言区盖楼讨论!
以上是关于多线程之脏读 代码示例及处理的主要内容,如果未能解决你的问题,请参考以下文章