Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java: Synchronizing on primitives?

In our system, we have a method that will do some work when it's called with a certain ID:

public void doWork(long id) { /* ... */ }

Now, this work can be done concurrently for different IDs, but if the method is called with the same ID by 2 threads, one thread should block until it's finished.

The simplest solution would be to have a Map that maps from the Long ID to some arbitrary object that we can lock on. One problem I foresee with this is that we can have tons of IDs in the system and this map will keep growing every day.

Ideally, I think we need a system where we each thread will fetch a lock object, lock when possible, do the work, then signal that we're done with the lock. If it's clear that nobody else is using this particular lock, then safely remove it from the lock map to prevent the memory leak.

I imagine this must be a pretty common scenario so I'm hoping there is an existing solution out there. Anyone know of any?

like image 322
Outlaw Programmer Avatar asked Feb 17 '10 15:02

Outlaw Programmer


People also ask

Can primitive type be synchronized?

synchronized is not applicable with primitive argument.

Can we use synchronized block for primitives in Java?

There is also a synchronized statement in Java that forces threads to execute a block of code sequentially. Using these primitives, correct concurrent access to a shared data structure can be programed.

Which are the synchronization primitives?

Mutex, event, conditional variables and semaphores are all synchronization primitives.

How are synchronization primitives implemented?

Several synchronization primitives have been introduced to aid in multithreading the kernel. These primitives are implemented by atomic operations and use appropriate memory barriers so that users of these primitives do not have to worry about doing it themselves.


2 Answers

I invented a thing like that for myself some time ago. I call it an equivalence-class lock, meaning, it locks on all of the things that are equal to the given thing. You can get it from my github, and use it subject to the Apache 2 license, if you like, or just read it and forget it!

like image 110
Jonathan Feinberg Avatar answered Nov 02 '22 21:11

Jonathan Feinberg


You can try something with a ReentrantLock, such that you have a Map<Long,Lock>. Now after lock.release() You can test lock.hasQueuedThreads(). If that returns false you can remove it from the Map.

like image 43
John Vint Avatar answered Nov 02 '22 20:11

John Vint