java 获取调用对象的方法,Java同步块使用方法调用获取同步对象

We are writing some locking code and have run into a peculiar question. We use a ConcurrentHashMap for fetching instances of Object that we lock on. So our synchronized blocks look like this

synchronized(locks.get(key)) { ... }

We have overridden the get method of ConcurrentHashMap to make it always return a new object if it did not contain one for the key.

@Override

public Object get(Object key) {

Object o = super.get(key);

if (null == o) {

Object no = new Object();

o = putIfAbsent((K) key, no);

if (null == o) {

o = no;

}

}

return o;

}

But is there a state in which the get-method has returned the object, but the thread has not yet entered the synchronized block. Allowing other threads to get the same object and lock on it.

We have a potential race condition were

thread 1: gets the object with key A, but does not enter the synchronized block

thread 2: gets the object with key A, enters a synchronized block

thread 2: removes the object from the map, exits synchronized block

thread 1: enters the synchronized block with the object that is no longer in the map

thread 3: gets a new object for key A (not the same object as thread 1 got)

thread 3: enters a synchronized block, while thread 1 also is in its synchronized block both using key A

This situation would not be possible if java entered the synchronized block directly after the call to get has returned. If not, does anyone have any input on how we could remove keys without having to worry about this race condition?

解决方案

you have 2 options:

a. you could check the map once inside the synchronized block.

Object o = map.get(k);

synchronized(o) {

if(map.get(k) != o) {

// object removed, handle...

}

}

b. you could extend your values to contain a flag indicating their status. when a value is removed from the map, you set a flag indicating that it was removed (within the sync block).

CacheValue v = map.get(k);

sychronized(v) {

if(v.isRemoved()) {

// object removed, handle...

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值