11934

Synchronization on boxed primitive

I am new to multithreaded programming. So I need some help to this issue. I get a findbugs bug with synchronization on a boxed primitive:

http://findbugs.sourceforge.net/bugDescriptions.html#DL_SYNCHRONIZATION_ON_BOXED_PRIMITIVE

I tried some solutions on this site but it doesn't work as I expected. Sometimes I get a similar error from findbugs.

My code needs a lock on a id which I pass to a constructor, here is some pseudocode:

public class MyClass{ public MyClass(long id){ synchronized(id){ // do some stuff } } }

The problem is, that only threads with the same id should block on the synchronized block. Threads with different ids should work simultaneously.

I also tried something like this, but it doesn't work for me:

public class MyClass{ private static final ConcurrentHashMap<Long, Object> myHashMap = new ConcurrentHashMap<Long, Object>(); public MyClass(long id){ Object object = getObject(id); synchronized(object){ // do some stuff } } private Object getObject(long id){ if(!myHashMap.contains(id)){ writeObject(id); } return myHashMap.get(id); } private synchronized void writeObject(long id){ if(!myHashMap.contains(id)){ myHashMap.put(id, new Object()); } } }

In the second example you see, I tried to put an object per id in the hashmap, but with an unit test I realized, that threads with same id get in the synchronized block. But they should not do. I will be very thankful if someone has another solution or how to handle these problems.

Answer1:

Good for you that you wrote an unit test! For future reference: You want to test all kinds of edge values, which means for numbers at least 0, -1, 1, MAX_VALUE, MIN_VALUE - that would've caught the second bug you missed :-)

The problem with your code is that: synchronized(l) {} translates to: synchronized(Long.valueOf(l)){}. valueOf caches Longs in the range -128, 127 but even this is optional (the JLS only requires it for integers surprisingly!). Consequently as soon as your ids are larger than 127 your whole scheme falls apart.

Your second method is the way to go, but you cannot just make the method synchronized - that will just synchronize on this, so doesn't guarantee atomicity for the static map.

Instead do something like this:

Object newLock = new Object(); Object oldLock = map.putIfAbsent(id, newLock); Object lock = oldLock != null ? oldLock : newLock; synchronized(lock) { }

Recommend

  • Selection sort growing ordered ranges from both ends
  • java rmi deadlock
  • Mutate value by using a value from a different row in a tibble
  • Serial communication over USB converter in Python - how to aproach this?
  • How to find problematic thread in Eclipse remote debugger?
  • longest common subsequence: why is this wrong?
  • Issue with std::thread when using g++ in 32-bit MinGW 4.8.0
  • datatables left join c#
  • Powerpoint 2010 VSTO AddIn taskpane on multiple Windows
  • limited threads in soapUI free version
  • Java inject implementation using TypeLiteral
  • Calling a constructor through reflection in scala 2.10
  • oauth2client.client.HttpAccessTokenRefreshError: invalid_grant: Invalid JWT
  • Parallel sieve of Eratosthenes - Java Multithreading
  • In Akka, is ActorContext thread safe?
  • Responsive left sidebar open close
  • Prevent page break in text block with iText, XMLWorker
  • Why people use prototype in javascript when it is easy to inherit using apply () and call () methods
  • unable to get jsonEncode in magento2
  • C++ friend class std::vector
  • SyntaxError: (irb):26: both block arg and actual block given
  • Possible to “watch” both HAML and SASS at the same time?
  • How to specify input and output paths from cmd.exe for a PowerShell script?
  • Spring boot 2.0.0.M4 required a bean named 'entityManagerFactory' that could not be found
  • How can I set a binding to a Combox in a UserControl?
  • Create DicomImage from scratch using Dcmtk
  • Alternative To body {overflow:scroll;} That Will Prevent Page Jostling/Wriggling?
  • Setting up SourceTree to merge unity3d scenes with UnityYAMLMerge
  • Record samples being played with OpenAL
  • Spray.io: When (not) to use non-blocking route handling?
  • Join two tables and save into third-sql
  • How to model a transition system with SPIN
  • ORA-29908: missing primary invocation for ancillary operator
  • Transpose CSV data with awk (pivot transformation)
  • JTable with a ScrollPane misbehaving
  • Angular 2 constructor injection vs direct access
  • unknown Exception android
  • failed to connect to specific WiFi in android programmatically
  • Converting MP3 duration time
  • How can I use threading to 'tick' a timer to be accessed by other threads?