Making static ReentrantLocks
Asked Answered
D

2

3

I've stumbled upon this thread some time ago: Does making a reentrant lock static and make it a mutex? and I have an additional question on my own:

Im interested if creating a private static final ReentrantLock lock is not considered a code smell? I've read that static variables are evil, yet my current use case Im working on looks like ideal place to use one.

Anyone care to help?

Edit with details: I have this class, call it FileProcessor which does a given job in another thread. My use case is spinning up a few of these instances of this class and doing those jobs. But what I want to do is to make sure only one of them will make this job at once and they will take turns in performing the work.

So I figured out Ill give them a static ReentrantLock that will lock() as first thing in run() block and unlock() as last. This way they have a shared lock that will guard the processing synchronization.

Thanks.

Dawdle answered 8/12, 2017 at 21:12 Comment(3)
Saying "static variables are evil" without any context is just useless. Without seeing your use case, it's hard to say whether it's a good idea or not. Generally speaking there's nothing evil in static. You can abuse it of course, but you can abuse a lot of things.Abramabramo
edited and added more detailsDawdle
No problem in using a static ReentrantLock. It seems to fit your use case well. You can also use synchronized (this) {} to achieve the same thing without using an explicit lock. This does not provide as much granularity, of course.Navy
H
3

Using a static Lock for synchronization at the class level is absolutely normal. You can also use

synchronized (FileProcessor.class) {
    //your code
}
Hendrika answered 9/12, 2017 at 2:2 Comment(1)
Upvoted, but I think it is worth suggesting that the poster consider using an ExecutorService. Even if you don't use a non-blocking model now, it will be easier to move to one.Aeneas
S
0

For some time, using a global variable was the best option. With the Concurrency API, you have much more simple approaches, for example:

  1. You can create a Runnable that executes the code in FileProcessor and submit it to an Executor. You configure the executor to single threaded and you're done.

  2. If you have several places where you can start a job and you want to make sure that only one ever runs. Imagine you want to run it right when the program starts and then at 16:00. Now someone starts the program at 15:59 - the job might be started twice. To avoid this, protect the code with an AtomicBoolean:

    private AtomicBoolean guard = new AtomicBoolean(true);
    
    if (guard.getAndSet(false)) {
        try {
            ... do job ...
        } finally {
            guard.set(true);
        }            
    }
    
Scribe answered 30/12, 2017 at 10:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.