[concurrency-interest] Thread subclass check locking is a bottleneck
Gregg Wonderly
gregg at cytetech.com
Mon Feb 16 17:44:51 EST 2009
Gregg Wonderly wrote:
> David Holmes wrote:
>> The "table" is an unsynchronized data structure hence it has to be
>> protected
>> by a global lock of some form. I don't see any reason to synchronize
>> on the
>> Class object as we're not updating state in the Class.
We are validating the usability of that class and writing that into the
softCache. The comment below,
> I guess the question is whether it's safe to perform the audit on the
> same class, simultaneously.
goes back to locking on the Class. The data structure needs to be queried, some
action performed, and then the result of that action put into the table. The
first and last steps do require synchronized access to the concurrently updated
table. However the validation step may only require the step to be performed
exactly once, and/or not concurrently with another thread. So that's why I'm
suggesting locking on the class.
I was inferring the lock on cl to be in a context like the following
private static boolean isCCLOverridden(Class cl) {
if (cl == Thread.class)
return false;
Boolean result = null;
synchronized (subclassAudits) {
result = (Boolean) subclassAudits.get(cl);
}
if (result == null) {
synchronized( cl ) {
/*
* Note: only new Boolean instances (i.e., not Boolean.TRUE or
* Boolean.FALSE) must be used as cache values, otherwise cache
* entry will pin associated class.
*/
result = new Boolean(auditSubclass(cl));
}
synchronized (subclassAudits) {
Boolean nresult;
if( (nresult = subclassAudits.get(cl)) == null )
subclassAudits.put(cl, result);
else
result = nresult;
}
}
return result.booleanValue();
}
this looks very much like putIfAbsent and exactly the locking perspective that
would occur with the use of ConcurrentHashMap. The only issue is whether we
want to do the locking on Class while the audit occurs.
Gregg Wonderly
>> It would certainly be better to have some kind of concurrently accessible
>> structure - especially as it is called twice per construction (once for
>> current class, once for parent class). If the SoftCache were a concurrent
>> map then I don't think any synchronization would be needed
>
> I guess the question is whether it's safe to perform the audit on the
> same class, simultaneously. If that's okay, then I agree that using a
> concurrent map would be more in line with the fact that this is a
> concurrently accessed bit of code that seems to have a highly contested
> (in my application) lock.
>
> Gregg Wonderly
>
>> David Holmes
>>
>>> -----Original Message-----
>>> From: concurrency-interest-bounces at cs.oswego.edu
>>> [mailto:concurrency-interest-bounces at cs.oswego.edu]On Behalf Of Gregg
>>> Wonderly
>>> Sent: Tuesday, 17 February 2009 3:33 AM
>>> To: concurrency-interest
>>> Subject: [concurrency-interest] Thread subclass check locking is a
>>> bottleneck
>>>
>>>
>>> I have an old application that implements it's own thread pooling. But,
>>> this is an issue simply related to the java.lang.Thread constructor
>>> locking on subclass construction. I am seeing stuck threads of the
>>> form:
>>>
>>> java.lang.Thread.State: BLOCKED (on object monitor)
>>> at java.lang.Thread.isCCLOverridden(Thread.java:1521)
>>> - waiting to lock <0xaca0a778> (a sun.misc.SoftCache)
>>> at java.lang.Thread.init(Thread.java:338)
>>> at java.lang.Thread.<init>(Thread.java:419)
>>>
>>> The global lock used there seems to be an unfortunate choice. The code
>>> I see on the internet is:
>>>
>>> 1615 private static boolean isCCLOverridden(Class cl) {
>>> 1616 if (cl == Thread.class)
>>> 1617 return false;
>>> 1618 Boolean result = null;
>>> 1619 synchronized (subclassAudits) {
>>> 1620 result = (Boolean) subclassAudits.get(cl);
>>> 1621 if (result == null) {
>>> 1622 /*
>>> 1623 * Note: only new Boolean instances
>>> (i.e., not Boolean.TRUE or
>>> 1624 * Boolean.FALSE) must be used as cache
>>> values, otherwise cache
>>> 1625 * entry will pin associated class.
>>> 1626 */
>>> 1627 result = new Boolean(auditSubclass(cl));
>>> 1628 subclassAudits.put(cl, result);
>>> 1629 }
>>> 1630 }
>>> 1631 return result.booleanValue();
>>> 1632 }
>>>
>>> Wouldn't it be more prudent for the lock held during
>>> auditSubclass to be on cl and not the global table?
>>>
>>> Gregg Wonderly
>>>
>>>
>>> _______________________________________________
>>> Concurrency-interest mailing list
>>> Concurrency-interest at cs.oswego.edu
>>> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>>
>>
>>
>
>
>
More information about the Concurrency-interest
mailing list