Java 在局部变量插图上同步
Java synchronized on local variable illustration
这是来自apache zookeeper的方法源码,classDataTree
/**
* update the count of this stat datanode
*
* @param lastPrefix
* the path of the node that is quotaed.
* @param diff
* the diff to be added to the count
*/
public void updateCount(String lastPrefix, int diff) {
String statNode = Quotas.statPath(lastPrefix);
DataNode node = nodes.get(statNode);
StatsTrack updatedStat = null;
if (node == null) {
// should not happen
LOG.error("Missing count node for stat " + statNode);
return;
}
synchronized (node) {
updatedStat = new StatsTrack(new String(node.data));
updatedStat.setCount(updatedStat.getCount() + diff);
node.data = updatedStat.toString().getBytes();
}
// now check if the counts match the quota
String quotaNode = Quotas.quotaPath(lastPrefix);
node = nodes.get(quotaNode);
StatsTrack thisStats = null;
if (node == null) {
// should not happen
LOG.error("Missing count node for quota " + quotaNode);
return;
}
...
我的问题是为什么它在节点对象上同步?如果其他线程从 HashMap 节点中删除节点,则节点无效。这里有什么问题吗?
My question is why it synchronized on the node object?
node
充当同步对象。线程在一个对象上同步是很常见的,该对象的内部状态可以被其中一些线程修改。这种同步强加了线程之间的顺序。因此避免了竞争条件。您的代码没有显示它,但项目的其他部分可能 node
的内容被其他线程修改。因此,所有在 node
上同步的线程将是一致的。
If other thread remove the node from nodes which is a HashMap, then node becomes invalid. Is there some problem here?
如果从hashmap中移除node
,并不意味着该节点将无效。它也不会被垃圾收集器销毁,因为它在您显示的代码中被引用。
node
只有在整个程序中不再引用时才会失效。
My question is why it synchronized on the node object?
在本地同步似乎很奇怪,但请注意本地的值来自函数外部(nodes
,这可能是一个实例成员) .因此它所同步的对象将可用于多个线程,并且显然该方法中的代码需要确保它不会 运行 同时在多个线程上用于同一 node
。
在这种情况下,显然它正在保护 node.data
的更新,并且有充分的理由:它正在获取 node.data
,修改该数据,然后用结果更新 node.data
。两个线程同时执行此操作可能会影响彼此的工作。
If other thread remove the node from nodes which is a HashMap, then node becomes invalid.
不,它只是不在 HashMap 中了。从地图中删除它不会修改节点。
这是来自apache zookeeper的方法源码,classDataTree
/**
* update the count of this stat datanode
*
* @param lastPrefix
* the path of the node that is quotaed.
* @param diff
* the diff to be added to the count
*/
public void updateCount(String lastPrefix, int diff) {
String statNode = Quotas.statPath(lastPrefix);
DataNode node = nodes.get(statNode);
StatsTrack updatedStat = null;
if (node == null) {
// should not happen
LOG.error("Missing count node for stat " + statNode);
return;
}
synchronized (node) {
updatedStat = new StatsTrack(new String(node.data));
updatedStat.setCount(updatedStat.getCount() + diff);
node.data = updatedStat.toString().getBytes();
}
// now check if the counts match the quota
String quotaNode = Quotas.quotaPath(lastPrefix);
node = nodes.get(quotaNode);
StatsTrack thisStats = null;
if (node == null) {
// should not happen
LOG.error("Missing count node for quota " + quotaNode);
return;
}
...
我的问题是为什么它在节点对象上同步?如果其他线程从 HashMap 节点中删除节点,则节点无效。这里有什么问题吗?
My question is why it synchronized on the node object?
node
充当同步对象。线程在一个对象上同步是很常见的,该对象的内部状态可以被其中一些线程修改。这种同步强加了线程之间的顺序。因此避免了竞争条件。您的代码没有显示它,但项目的其他部分可能 node
的内容被其他线程修改。因此,所有在 node
上同步的线程将是一致的。
If other thread remove the node from nodes which is a HashMap, then node becomes invalid. Is there some problem here?
如果从hashmap中移除node
,并不意味着该节点将无效。它也不会被垃圾收集器销毁,因为它在您显示的代码中被引用。
node
只有在整个程序中不再引用时才会失效。
My question is why it synchronized on the node object?
在本地同步似乎很奇怪,但请注意本地的值来自函数外部(nodes
,这可能是一个实例成员) .因此它所同步的对象将可用于多个线程,并且显然该方法中的代码需要确保它不会 运行 同时在多个线程上用于同一 node
。
在这种情况下,显然它正在保护 node.data
的更新,并且有充分的理由:它正在获取 node.data
,修改该数据,然后用结果更新 node.data
。两个线程同时执行此操作可能会影响彼此的工作。
If other thread remove the node from nodes which is a HashMap, then node becomes invalid.
不,它只是不在 HashMap 中了。从地图中删除它不会修改节点。