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:46

You very likely have a deadlock.

If you want to avoid deadlocks, every thread must always acquire locks in the same order. When you use String.intern() to get your locks, you are locking on an instance that any code in the entire JVM has access to, and lock on. Most likely, other threads in your own code are deadlocking, but it doesn't have to be.

I'm not sure what you mean in your answer by "key.intern() guarantee uniqueness". The intern() method reduces uniqueness by returning the same object for every string that's equivalent.

  String s1 = new String(new char[] { 'c', 'o', 'm', 'm', 'o', 'n' }).intern();
  String s2 = new String("commo" + (s1.charAt(s1.length() - 1)).intern();
  String s3 = "common";
  if ((s1 == s2) && (s1 == s3))
    System.out.println("There's only one object here.");

The code above will demonstrate that even though you created two unique instances, by interning them, you replaced them with a single, canonical instance.

There's danger any time you use an object that's visible outside your own code as a lock. Try to stick to private members, objects that you don't allow to escape from your own stack, etc.

查看更多
Lonely孤独者°
3楼-- · 2019-04-28 01:48

There is not enough code here to tell what is going wrong. It could be a bottleneck as has been mentioned, but at least one thread should be running (with fairly heavy CPU usage) for that to happen, or a thread that has the lock is put to sleep without releasing the lock.

A deadlock is another possibility but that would require synchronization on two separate locks on multiple threads, and you have shown only one lock object here.

It is really impossible to determine without more information.

查看更多
SAY GOODBYE
4楼-- · 2019-04-28 01:49

Quite. The problem is that key.intern() isn’t really that unique because it’s returning a string from a pool. String.intern() might return the same object even when used on different objects. Try using key itself or a different object altogether.

查看更多
虎瘦雄心在
5楼-- · 2019-04-28 01:52

key.intern() guarantee uniqueness because key.intern() returns a string from String constants pool.

http://java.sun.com/j2se/1.4.2/docs/api/java/lang/String.html#intern() intern

public String intern() Returns a canonical representation for the string object. A pool of strings, initially empty, is maintained privately by the class String.

查看更多
Luminary・发光体
6楼-- · 2019-04-28 01:53

I posted a related question to this once that you might want to take a look at: Problem with synchronizing on String objects?

What I learned was: using intern'ed Strings for synchronization is a bad practice.

查看更多
登录 后发表回答