I am looking for mechanism which will help me to implement following pattern (pseudocode):
TimeoutLock lock = new TimeoutLock();
while(condition) {
prepare();
lock.enter(); //cannot enter until specified lock timeout elapses
execute();
lock.lockFor(2 minutes);
finish();
}
I need to limit invocations to execute to occur no more often, than some specified interval (for example, two minutes), but I do not want to block prepare or execute if it is not necessary. I am wondering if java supports any locking mechanism, which 'vanishes' after some time. Requirement is that, of course, lock does not pass through even if it's entered by the same thread, which locked it.
I was thinking about solution involving semaphore and TimerTask, or calculating deadline by myself and sleeping for superfluous time, but I wonder if something like this is already available.
Thanks
The below will do
basically you have a semphore which will only let you access if there is a permit available, I this case zero permits. So it will try for 2000 seconds before finally giving up
->
Semaphore s = new Semaphore(0);
Object lock = new Object();
synchronized(lock)
{
execute();
s.tryAcquire(2,TimeUnit.Minutes)
}
Thread.sleep is a lame and low level way of doing it. Not recommended
No need for a special class:
synchronized(lock) {
execute();
Thread.sleep(120 * 1000)
}
As Marko says, you very likely want to do this by handing the work off to a scheduler of some sort, rather than blocking the thread.
But if you do want to do this, i would suggest that you do it by recording a timestamp on exiting the critical section, and having entering threads wait for a period after that to pass. Something like:
public class TimeoutLock {
private boolean held;
private long available;
public void enter() throws InterruptedException {
acquire();
long pause;
while ((pause = available - System.currentTimeMillis()) > 0L) {
Thread.sleep(pause);
}
}
private synchronized void acquire() throws InterruptedException {
while (held) {
wait();
}
held = true;
}
public synchronized void lockFor(long period) {
held = false;
available = System.currentTimeMillis() + period;
notify();
}
}
You could use the sleep
sleep(1000);
Related
I am using a ScheduledExecutorService to schedule and process jobs across several threads. In my application, a job can schedule a new job (on the same ScheduledExecutorService), as some kind of follow-up action.
In the main thread, I want to wait until all jobs are finished, as a synchronization point. There are the shutdown() and awaitTermination() methods, but this disallows any running or pending job to schedule a new job. In my case, I actually want to allow this, accepting the risk that we will never finish (or hit some timeout).
How do I wait for all jobs and possibly their follow-up jobs to finish?
It's possible by keeping track of the number of active jobs. Effectively, each job that you submit must be wrapped as follows (pseudo code):
increase active jobs by one
try {
run actual job
} finally {
decrease active jobs by one
}
Of course the ScheduledExecutorService needs to be fully encapsulated for this to work.
The next step is to find the right concurrent mechanism for this, that doesn't introduce any busy waiting.
A quick and dirty attempt using a Lock with a Condition that signals no more jobs:
private final Lock lock = new ReentrantLock();
private final Condition noJobs = lock.newCondition();
private long jobCount = 0;
private void increaseJobCount() {
lock.lock();
try {
jobCount++;
} finally {
lock.unlock();
}
}
private void decreaseJobCount() {
lock.lock();
try {
jobCount--;
if (jobCount == 0) {
noJobs.signalAll();
}
} finally {
lock.unlock();
}
}
public void awaitNoJobs() throws InterruptedException {
lock.lock();
try {
while (jobCount > 0) {
noJobs.await();
}
} finally {
lock.unlock();
}
}
I checked some other known concurrent classes, but apart from a BlockingQueue / BlockingDeque I couldn't find any. Those take up more memory though, as you'd have to add and remove something for each job that's submitted. A CountDownLatch comes close but doesn't allow increasing the count.
I am learning multi-threads programming in java recently. And I don't understand why the following test case will fail. Any explanation will be much appreciated.
Here is MyCounter.java.
public class MyCounter {
private int count;
public synchronized void incrementSynchronized() throws InterruptedException {
int temp = count;
wait(100); // <-----
count = temp + 1;
}
public int getCount() {
return count;
}
}
This is my unit test class.
public class MyCounterTest {
#Test
public void testSummationWithConcurrency() throws InterruptedException {
int numberOfThreads = 100;
ExecutorService service = Executors.newFixedThreadPool(10);
CountDownLatch latch = new CountDownLatch(numberOfThreads);
MyCounter counter = new MyCounter();
for (int i = 0; i < numberOfThreads; i++) {
service.submit(() -> {
try {
counter.incrementSynchronized();
} catch (InterruptedException e) {
e.printStackTrace();
}
latch.countDown();
});
}
latch.await();
assertEquals(numberOfThreads, counter.getCount());
}
}
But if I remove wait(100) from the synchronized method incrementSynchronized, the test will succeed. I don't understand why wait(100) will affect the result.
Solomons suggestion to use sleep is a good one. If you use sleep instead of wait, you should see the test pass.
Using wait causes the thread to relinquish the lock, allowing other threads to proceed and overwrite the value in count. When the thread's wait times out, it acquires the lock again, then writes a value to count that may be stale by now.
The typical usage of wait is when your thread can't do anything useful until some condition is met. Some other thread eventually satisfies that condition and a notification gets sent that will inform the thread it can resume work. In the meantime, since there is nothing useful the thread can do, it releases the lock it is holding (because other threads need the lock in order to make progress meeting the condition that the thread is waiting for) and goes dormant.
Sleep doesn't release the lock so there won't be interference from other threads. For either the sleeping case or the case where you delete the wait call, the lock is held for the duration of the operation, nothing else can change count, so it is threadsafe.
Be aware that in real life, outside of learning exercises, sleeping with a lock held is usually not a great idea. You want to minimize the time that a task holds a lock so you can get more throughput. Threads denying each other the use of a lock is not helpful.
Also be aware that getCount needs to be synchronized as well, since it is reading a value written by another thread.
I used Object.wait(timeout) in my android app service. But it does not count time spent in "deep sleep mode". I use AlarmManager to wakeup my app periodically, so waking from deep sleep is not the problem. The problem is that wait(60000) not terminates after 100 seconds of deep sleep.
As i read on SystemClock help page, object.wait uses uptimeMillis() method, which stops counting in deep sleep. For my needs it will be better to use elapsedRealtime().
How can i implement an analogue of Object.wait(timeout) but using elapsedRealtime method? Or what can i use instead?
One of the tasks i use this method for is to generate "ping" packet to send via network when no other packets are in queue for some amount of time.
Instead of using plain Object.wait() or Thread.sleep() I would suggest you to use any of the following:
Use a java.util.concurrent.newScheduledThreadPool which gives you ability to schedule a task with fixed interval or delay. Initializing the thread pool with threadCount = 1 gives you a single thread.
Use a java.util.Timer which allows you to schedule TimerTask.
I think 1. is a preferred method.
In case you have specific requirement that you want to plug in your timer object or use a specific or 3rd party timing provider, what you need to do is to write your own scheduler which wraps the ScheduledExecutorService, then convert the time using your own timer or get time from your own timer. Basically you launch a scheduled task on the wrapped service with your own time calculation.
I have a sample of such scheduler in my actor model as below. Take a look at the DefaultScheduler in this package. It might be a bit buggy (I haven't tested it fully yet) but it should give you a good idea.
http://sourceforge.net/p/jalgo/code-0/HEAD/tree/trunk/src/org/as/algo/threading/
You mentioned(at comments) interrupt() causes termination(kill) the thread, while this is completely wrong, it just throws an exception to the waiting/joining/sleeping thread.
public void Foo implements Runnable{
public void run(){
//do some work
try{Thread.sleep(10000);}catch(Exception ex){/*when thread got interrupted*/}
//do something else
}
}
the issue is here, because you put all the business inside a try block, so interrupting causes code jump into the catch block where there is no any business after this, so this is not a thread thing.
Not sure if it does exactly what you want but I wrote this to pause for a certain period of time but to let other threads wake me up prematurely.
It uses a BlockingQueue internally to do it's sleeping so it avoid using sleep and wait and all the grief that comes with them.
Not sure how it would act under Android, I don't work with it, but I suspect your existing AlarmManager work will adapt.
/**
* Use one of these to doze for a certain time.
*
* The dozing is fully interruptable.
*
* Another thread can stop the caller's doze with either a wakeup call or an abort call.
*
* These can be interpreted in any way you like but it is intended that a Wakeup is
* interpreted as a normal awakening and should probably be treated in exactly the
* same way as an Alarm. An Abort should probably be interpreted as a suggestion
* to abandon the process.
*/
public class Doze {
// Special alarm messages.
public enum Alarm {
// Standard timeout.
Alarm,
// Forced wake from your doze.
Wakeup,
// Abort the whole Doze process.
Abort;
}
// My queue to wait on.
private final BlockingQueue<Alarm> doze = new ArrayBlockingQueue<>(1);
// How long to wait by default.
private final long wait;
public Doze(long wait) {
this.wait = wait;
}
public Doze() {
this(0);
}
public Alarm doze() throws InterruptedException {
// Wait that long.
return doze(wait);
}
public Alarm doze(long wait) throws InterruptedException {
// Wait that long.
Alarm poll = doze.poll(wait, TimeUnit.MILLISECONDS);
// If we got nothing then it must be a normal wakeup.
return poll == null ? Alarm.Alarm : poll;
}
public void wakeup() {
// Just post a Wakeup.
doze.add(Alarm.Wakeup);
}
public void abort() {
// Signal the system to abort.
doze.add(Alarm.Abort);
}
private static long elapsed ( long start ) {
return System.currentTimeMillis() - start;
}
// Test code.
public static void main(String[] args) throws InterruptedException {
// Doze for 1 second at a time.
final Doze d = new Doze(1 * 1000);
final long start = System.currentTimeMillis();
// Start a dozing thread.
new Thread(new Runnable() {
#Override
public void run() {
try {
Alarm a = d.doze();
// Wait forever until we are aborted.
while (a != Alarm.Abort) {
System.out.println(elapsed(start) + ": Doze returned " + a);
a = d.doze();
}
System.out.println(elapsed(start) + ": Doze returned " + a);
} catch (InterruptedException ex) {
// Just exit on interrupt.
}
}
}).start();
// Wait for a few seconds.
Thread.sleep(3210);
// Wake it up.
d.wakeup();
// Wait for a few seconds.
Thread.sleep(4321);
// Abort it.
d.abort();
}
}
I'm trying to find a less clunky solution to a Java concurrency problem.
The gist of the problem is that I need a shutdown call to block while there are still worker threads active, but the crucial aspect is that the worker tasks are each spawned and completed asynchronously so the hold and release must be done by different threads. I need them to somehow send a signal to the shutdown thread once their work has completed. Just to make things more interesting, the worker threads cannot block each other so I'm unsure about the application of a Semaphore in this particular instance.
I have a solution which I think safely does the job, but my unfamiliarity with the Java concurrency utils leads me to think that there might be a much easier or more elegant pattern. Any help in this regard would be greatly appreciated.
Here's what I have so far, fairly sparse except for the comments:
final private ReentrantReadWriteLock shutdownLock = new ReentrantReadWriteLock();
volatile private int activeWorkerThreads;
private boolean isShutdown;
private void workerTask()
{
try
{
// Point A: Worker tasks mustn't block each other.
shutdownLock.readLock().lock();
// Point B: I only want worker tasks to continue if the shutdown signal
// hasn't already been received.
if (isShutdown)
return;
activeWorkerThreads ++;
// Point C: This async method call returns immediately, soon after which
// we release our lock. The shutdown thread may then acquire the write lock
// but we want it to continue blocking until all of the asynchronous tasks
// have completed.
executeAsynchronously(new Runnable()
{
#Override
final public void run()
{
try
{
// Do stuff.
}
finally
{
// Point D: Release of shutdown thread loop, if there are no other
// active worker tasks.
activeWorkerThreads --;
}
}
});
}
finally
{
shutdownLock.readLock().unlock();
}
}
final public void shutdown()
{
try
{
// Point E: Shutdown thread must block while any worker threads
// have breached Point A.
shutdownLock.writeLock().lock();
isShutdown = true;
// Point F: Is there a better way to wait for this signal?
while (activeWorkerThreads > 0)
;
// Do shutdown operation.
}
finally
{
shutdownLock.writeLock().unlock();
}
}
Thanks in advance for any help!
Russ
Declaring activeWorkerThreads as volatile doesn't allow you to do activeWorkerThreads++, as ++ is just shorthand for,
activeWorkerThreads = activeWorkerThreads + 1;
Which isn't atomic. Use AtomicInteger instead.
Does executeAsynchronously() send jobs to a ExecutorService? If so you can just use the awaitTermination method, so your shutdown hook will be,
executor.shutdown();
executor.awaitTermination(1, TimeUnit.Minutes);
You can use a semaphore in this scenario and not require a busy wait for the shutdown() call. The way to think of it is as a set of tickets that are handed out to workers to indicate that they are in-flight. If the shutdown() method can acquire all of the tickets then it knows that it has drained all workers and there is no activity. Because #acquire() is a blocking call the shutdown() won't spin. I've used this approach for a distributed master-worker library and its easy extend it to handle timeouts and retrials.
Executor executor = // ...
final int permits = // ...
final Semaphore semaphore = new Semaphore(permits);
void schedule(final Runnable task) {
semaphore.acquire();
try {
executor.execute(new Runnable() {
#Override public run() {
try {
task.run();
} finally {
semaphore.release();
}
}
});
} catch (RejectedExecutionException e) {
semaphore.release();
throw e;
}
}
void shutDown() {
semaphore.acquireUninterruptibly(permits);
// do stuff
}
ExecutorService should be a preferred solution as sbridges mentioned.
As an alternative, if the number of worker threads is fixed, then you can use CountDownLatch:
final CountDownLatch latch = new CountDownLatch(numberOfWorkers);
Pass the latch to every worker thread and call latch.countDown() when task is done.
Call latch.await() from the main thread to wait for all tasks to complete.
Whoa nelly. Never do this:
// Point F: Is there a better way to wait for this signal?
while (activeWorkerThreads > 0)
;
You're spinning and consuming CPU. Use a proper notification:
First: synchronize on an object, then check activeWorkerThreads, and wait() on the object if it's still > 0:
synchronized (mutexObject) {
while (activeWorkerThreads > 0) {
mutexObject.wait();
}
}
Second: Have the workers notify() the object after they decrement the activeWorkerThreads count. You must synchronize on the object before calling notify.
synchronized (mutexObject) {
activeWorkerThreads--;
mutexObject.notify();
}
Third: Seeing as you are (after implementing 1 & 2) synchronizing on an object whenever you touch activeWorkerThreads, use it as protection; there is no need for the variable to be volatile.
Then: the same object you use as a mutex for controlling access to activeWorkerThreads could also be used to control access to isShutdown. Example:
synchronized (mutexObject) {
if (isShutdown) {
return;
}
}
This won't cause workers to block each other except for immeasurably small amounts of time (which you likely do not avoid by using a read-write lock anyway).
This is more like a comment to sbridges answer, but it was a bit too long to submit as a comment.
Anyways, just 1 comment.
When you shutdown the executor, submitting new task to the executor will result in unchecked RejectedExecutionException if you use the default implementations (like Executors.newSingleThreadExecutor()). So in your case you probably want to use the following code.
code:
new ThreadPoolExecutor(1,
1,
1,
TimeUnit.HOURS,
new LinkedBlockingQueue<Runnable>(),
new ThreadPoolExecutor.DiscardPolicy());
This way, the tasks that were submitted to the executor after shutdown() was called, are simply ignored. The parameter above (1,1... etc) should produce an executor that basically is a single-thread executor, but doesn't throw the runtime exception.
First, this is a near duplicate of:
How to differentiate when wait(long timeout) exit for notify or timeout?
But it is a new follow-on question.
Having this wait declaration:
public final native void wait(long timeout) throws InterruptedException;
It could exit by InterruptedException, or by timeout, or because Notify/NotifyAll method was called in another thread, Exception is easy to catch but...
My code absolutely needs to know if the exit was from timeout or notify. (In the future, this code needs to be redesigned, but that cannot be done now. So I need to know the reason for the exit from wait.)
Specifically, can someone give an example of using a ThreadLocal Boolean that is set to true only on notify() and where all this is inside an existing loop as shown below? (This was more or less the accepted answer in the other thread, but no specific code example was given. I'm not all that familiar with Java, so I need a specific code example -- ideally in the context of the existing code below.)
public synchronized int getLastSequenceNumber() {
while (empty) {
try {
wait(waitTimeValue);
} catch (InterruptedException e) {}
}
empty = true;
return reportedSequenceNumber;
}
public synchronized void reconcileLastSequenceNumber(int sequenceNumber) {
empty = false;
this.reportedSequenceNumber = sequenceNumber;
notifyAll();
}
the Boolean "empty" serves a purpose outside of the specific question I'm asking here. I believe I will need to add another Boolean to fulfill the suggested answer from the original question. How would I integrate that proposed solution into the existing code snippet above? Thanks.
You might be better off using a Condition (and its await method) rather than built-in monitors, because await returns a boolean value indicating whether the wait timed out.
And even then, you must beware of spurious wakeup (which is indistinguishable from a call to signal.)
You should be using a loop as you currently are anyway, regardless of knowing whether the wait timed out - partly due to the possibility of spurious wakeups. However, I'm not at all sure that you really need to know whether the call exited due to notification or not.
Consider the situation where the notification occurs a nanosecond before the timeout vs the situation where the notification occurs a nanosecond after the timeout. What's the useful difference between the two? Fundamentally there's a race condition if the two occur at "about the same time".
As far as I can tell, wait() really doesn't let you tell whether the call timed out or not, but it shouldn't affect your code. You should be looping and testing something else that is a side-effect of the notification anyway.
It's not clear to me where a ThreadLocal would come into play to be honest - that's exactly the opposite of what you want if you need to be able to tell from the waiting thread whether the notifying the thread has reached a certain point. I don't think you need an extra variable at all - your empty is fine.
There's no direct way to report this with the builtin monitor API, but you could replace the wait() and other functions with a new implementation that tracks this explicitly (untested):
private int wait_ct = 0, signal_ct = 0;
public void checkedNotifyAll() {
synchronized {
signal_ct = wait_ct;
notifyAll();
}
}
public void checkedNotify() {
synchronized {
signal_ct++;
if (signal_ct > wait_ct)
signal_ct = wait_ct;
notify();
}
// Returns true if awoken via notify
public boolean waitChecked(long timeout, int nanos) throws InterruptedException {
synchronized(this) {
try {
wait_ct++;
super.wait(timeout, nanos);
if (signal_ct > 0) {
signal_ct--;
return true;
}
return false;
} finally {
wait_ct--;
if (signal_ct > wait_ct) signal_ct = wait_ct;
notify(); // in case we picked up the notify but also were interrupted
}
}
// Note: Do not combine this with normal wait()s and notify()s; if they pick up the signal themselves
// the signal_ct will remain signalled even though the checkedWait()s haven't been
// awoken, potentially resulting in incorrect results in the event of a spurious wakeup
This isn't necessarily a good way to do this, of course; if you timeout just before notify() is called, the signal condition may be lost, after all. You really should be waiting in a loop, checking some persistent condition.
This is an expanded version based on Jenkov's signal class. An exception is raised if it does not end with a Notify. Thought it might help as I ran into the same problem.
public class MonitorObject{
}
public class Signal{
MonitorObject myMonitorObject = new MonitorObject();
boolean wasSignalled = false;
public void doWait(int timeOut) throws InterruptedException,TimeoutException{
synchronized(myMonitorObject){
long startTime = System.currentTimeMillis();
long endTime = startTime + timeOut;
Log.d(TAG, String.format("MonitorStart time %d",startTime));
while(!wasSignalled){
long waitTime = endTime - System.currentTimeMillis();
if(waitTime > 0)
myMonitorObject.wait(waitTime);
else{
Log.e(TAG, String.format("Monitor Exit timeout error"));
throw new TimeoutException();
}
}
Log.d(TAG, String.format("MonitorLoop Exit currentTime=%d EndTime=%d",System.currentTimeMillis(),startTime + timeOut));
//Spurious signal so clear signal and continue running.
wasSignalled = false;
}
}
public void doNotify(){
synchronized(myMonitorObject){
wasSignalled = true;
myMonitorObject.notify();
}
}
}