https://docs.oracle.com/javase/tutorial/essential/concurrency/locksync.html说“在这个例子中,addName方法需要同步lastName和nameCount的更改,但也需要避免同步调用其他对象的方法。(从同步代码调用其他对象的方法可能会产生在Liveness一节中描述的问题。)”
我实际上想同步另一个对象。有3个类,AdminImpl,UserImpl,ServerState。
ServerState的同一示例是AdminImpl和UserImpl中的属性。
如果我用synchronized(this)
在UserImpl中编写一个临界区,它会同时获得UserImpl和作为UserImpl属性的ServerState示例的锁吗?(不同的)关键部分,因为要在AdminImpl的同步部分中,它需要同时获得这两个锁(AdminImpl和ServerState的),并且不能获取第二个,因为它是由UserImpl获取的?
我发现了一些关于同步的问题,例如java method synchronization objectConfusing Java synchronized method, synchronized(this), and synchronized classWhat's the difference between synchronized(this) and synchronized(some other object)
但没有一个涉及这一点
1条答案
按热度按时间jm81lzqq1#
同步并不查看它所锁定的示例的细节,它只是在每个Java对象都具有的“内在锁”上获取一个锁。
因此,它对第一个对象可能在其字段中引用的其他对象没有影响。
这里有一个例子,我认为说明你的问题。
ServerState
类包含一个可变的String
,名为state
,方法ServerState.addString
将String
追加到state
。编写
addString
方法是为了保证线程安全问题--它在获取state
的当前值和将新值赋给state
之间休眠。运行该程序,您将看到
state
的最终值是admin
,而我们期望的是useradmin
。确保您了解为什么会发生这种情况。
您可以尝试将
synchronized
添加到两个setStateString
方法中,您会发现这没有什么区别。现在只需将
addString
改为synchronized
,这样就解决了线程安全问题,因为现在state
字段的阅读和更新是原子性的--从其他线程的Angular 来看,这两个操作同时发生。