多线程之脏读 代码示例及处理

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两个实例变量同时被赋值,不存在脏读的基本环境。

脏读一定会出现操实例变量的情况下,这就是不同线程“争抢”实例变量的结果。


大家在学习过程中遇到过什么问题也欢迎在留言区盖楼讨论!

更多精彩推荐,请关注我们



以上是关于多线程之脏读 代码示例及处理的主要内容,如果未能解决你的问题,请参考以下文章

多线程的常用关键字及示例代码(synchronizedvolatile)

核心数据多线程:代码示例

一个简单示例看懂.Net 并行编程

Socket套接字及多线程实现在线群聊示例

Socket套接字及多线程实现在线群聊示例

Java并发多线程编程——集合类线程不安全之HashMap的示例及解决方案