deadlock on synchronized ( String intern())

2019-04-28 01:09发布

I user sun jdk 1.5 ThreadPoolExecutor( 24, 24,60,TimeUnit.SECONDS, new LinkedBlockingQueue()). soemtime I use jdb tool to find the status of all threads in thread pool are " waiting in a monitor", the code is :

    String key = getKey(dt.getPrefix(), id);
    synchronized (key.intern()) {      ----->

Is there a problem in "synchronized (key.intern()) " ?


I get following informatnio using jdb tool, the status of 24 threads is "waiting in a monitor", it means 24 threads are deadlock at "key.intern()".

(java.lang.Thread)0x28 pool-3-thread-2 waiting in a monitor

(java.lang.Thread)0x27 pool-3-thread-3 waiting in a monitor

(java.lang.Thread)0x1b pool-3-thread-4 waiting in a monitor

(java.lang.Thread)0x1a pool-3-thread-5 waiting in a monitor

(java.lang.Thread)0x19 pool-3-thread-6 waiting in a monitor

(java.lang.Thread)0x18 pool-3-thread-7 waiting in a monitor

(java.lang.Thread)0x17 pool-3-thread-8 waiting in a monitor ...

so the result is : in multi-threads environment, Sting intern() method may be deadlock, ok ?

11条回答
爷的心禁止访问
2楼-- · 2019-04-28 01:31

As Bombe says, key.intern() won't necessarily give you a very unique key to synchronize on.

You should be cautious about changing the code, however. You need to understand the locking strategy in the code before changing it. Removing the intern() call may give you code that appears to work correctly but contains a data race that will bite you later.

查看更多
霸刀☆藐视天下
3楼-- · 2019-04-28 01:31

String.intern() is a native method - that might be a cause of the problem.

查看更多
手持菜刀,她持情操
4楼-- · 2019-04-28 01:33

The code is almost certainly trying to synchronize actions that affect the same key. So it's calling intern() to ensure that the same key gets mapped to the same object, and therefore is valid as an object for synchronization.

The problem, if you're running into a bottleneck there (it's not a deadlock) is that you have too many operations coming in at the same time using the same key.

Rethink what needs to be synchronized.

查看更多
Explosion°爆炸
5楼-- · 2019-04-28 01:37

If you need to synchronize on a String, don't use a String instance as the mutex (interned or not). A string can be used to create a good mutex object, though: synchronizing on an ID.

查看更多
ら.Afraid
6楼-- · 2019-04-28 01:43

You are having two problems. The one is using String as the lock. The second one is deadlock.

If you using String as lock, you will lose the control of "who" and "where" will take that object lock.

Your deadlock issue, which may or may not caused by lock on String. However, the actual reason of deadlock is: "Your code can lead deadlock.". If it can happen, it will happen.

You must trace your threads' stacks to resolve deadlocks.

查看更多
闹够了就滚
7楼-- · 2019-04-28 01:44

How about using a unique string prefix with the locking value and using the String.intern() in the synchronized block. For example if you want to lock on the string "lock1", use a UUID prefix like this: "85e565b3-d440-46e7-93b6-69ee7e9a63ee-lock1". This type of string should not be already in the intern pool. i.e. chance of deadlock by other code is very low.

查看更多
登录 后发表回答