多线程执行同一个方法,为什么明明已经加了synchronized了,还是出现每次结果都不一样呢?

本文介绍JAVA多线程中的synchronized关键字作为對象锁的一些知识点

所谓对象锁,就是就是synchronized 给某个对象 加锁关于 对象锁 可参考:

synchronized可以修饰实例方法,如下形式:

这里synchronized 关键字锁住的昰当前对象。这也是称为对象锁的原因

上面代码也可写成这样:

使用synchronized关键字同步一个明显的特点是:MyObject类中定义有多个synchronized修饰的实例方法时,若多个线程拥有同一个MyObject类的对象则这些方法只能以同步的方式执行。即执行完一个synchronized修饰的方法后,才能执行另一个synchronized修饰的方法

//线程A与线程B 持有的是同一个对象:object

由于线程A和线程B持有同一个MyObject类的对象object,尽管这两个线程需要调用不同的方法但是必须是同步的,比如:线程B需要等待线程A执行完了methodA()方法之后它才能执行methodB()方法。

从上可以看出本文中讲述的 synchronized 锁的范围是整个对象。如果一个类中有多个synchronized修饰的同步方法且多个线程持有该类的同一个对象(该类的相同的对象),尽管它们调用不同的方法各个方法的执行也是同步的。

如果各个同步的方法之间没有共享变量或者说各个方法之间没有联系,但也只能同步执行这会影响效率。

五应用--使用synchronized避免 因数据不一致性而导致读脏数据的情况

methodA()负责更改用户名和密码。在现实中一个用户名对应着一个密码。。

methodB()负责读取用户名和密码

如果methodB()没有用synchronized 修饰,线程A茬调用methodA()执行到第7行更改了用户名,因某种原因(比如在第9行睡眠了)放弃了CPU

此时,如果线程B去执行methodB()那么读取到的用户名是线程A更改叻的用户名("a"),但是密码却是原来的密码("bb")因为,线程A睡眠了还没有来得及更改密码。

但是如果methodB()用synchronized修饰,那么线程B只能等待线程A执行完畢之后(即改了用户名也改了密码),才能执行methodB读取用户名和密码因此,就避免了数据的不一致性而导致的脏读问题

我要回帖

更多关于 多线程执行同一个方法 的文章

 

随机推荐