Jacques René Mesrine
Jacques René Mesrine

Reputation: 47805

Synchronizing on an interned String

use case example

current design

Taking inspiration from database sharding, I plan to use the first character of each userid as a synchronization key.

void login( String userid )
{
  String first = userid.substring(0, 1);
  synchronized( first.intern() )
  {
    // query the cache or database for a session token.
    // if session token exists, throw an exception
  }
}

questions

  1. I understand that using String#intern might overflow the permgen space. In my case, the string being dumped into permgen is a single Unicode character. Am I safe in using interned strings this way ?

Upvotes: 0

Views: 224

Answers (2)

Robert Munteanu
Robert Munteanu

Reputation: 68268

The PermGen overflow is not an issue. However:

  1. String.intern() is a heavyweight operation, since it requires locking the String constant pool. This will reduce your throughput;
  2. More importantly, you will synchronise on objects which 'escape' your control, e.g. if a library you use has a

    synchronized ("a") {
       // do stuff
    }
    

block somewhere, you will deadlock without knowing it. It's more or less the same issue as synchronising on Boolean or Integer values. I suggest you use your own locks for this.

Upvotes: 1

Tom Hawtin - tackline
Tom Hawtin - tackline

Reputation: 147154

To your question: Perm gen should be able to code with 65,536 one character Strings (should only be a few megs).

However:

  • This clearly isn't going to work on multi-process systems.
  • You run the risk of deadlock (if some other code is synchronising on such Strings).
  • It's really ugly.
  • Really you want a proper throttling(!), which shouldn't be at all difficult.

Upvotes: 1

Related Questions