I have an observer that can be called several times. If the onChange method of the observer is still running a second call should wait and the following calls should be ignored.
I used this:
Semaphore semaphore = new Semaphore(2,false);
...
public void onChange() {
if (!semaphore.tryAcquire()) return;
synchronized (semaphore) {
// do your stuff
semaphore.release();
}
}
Is this ok? Is there a better way?
Your logic looks good to me. As I read it 2 threads will be able to acquire the
Semaphorein any order. Any other threads trying to acquire will return and be ignored.The first thread to do the
synchronizedwill block the other one so only one thread will be working and one (max) will be waiting. As soon as the job has been completed andrelease()is called then another thread will be allowed into the semaphore. As soon as a thesynchronizedblock completes, the first waiting thread will start to work.Another way to do it would be with two
Semaphoreobjects with the 2nd one doing aacquireinstead of atryAcquire. But your way should work.As @herschel pointed out, I would do a
try/finallyaround “do your stuff” to guarantee that the semaphore is released. Something like: