I want to pause the main thread until the other thread finishes.
I tried CountDownLatch and semaphore. but none of them worked. I got the same error for both.
Caused by: java.lang.IllegalMonitorStateException: object not locked by thread before wait()
Code
public void testCountDownLatch(){
final CountDownLatch countDownLatch = new CountDownLatch(1);
new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(2000);
countDownLatch.countDown();
//Toast.makeText(MainActivity.this, "Latch Released", Toast.LENGTH_SHORT).show();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
try {
countDownLatch.wait();
Toast.makeText(this, "Yes! I am free now", Toast.LENGTH_SHORT).show();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
I tried to search for a few hours and was able to understand the cause of the error (wait() won't know if the countdown() gets called before it, in that case it would wait forever) but I couldn't able to understand how to fix it:(
You are calling the wrong method. You need to use await() instead of wait().
wait() is a method from Object and that method requires to synchronize over that object. Other synchronizers are normally preferred over Object#wait. Objects locked with Object#wait can be woken up with Object#notify or Object#notifyAll.
await() is a method of CountDownLatch and it waits for the CountDownLatch to count down (using CountDownLatch#countDown) to 0.
If you use Semaphore (basically the opposite of CountDownLatch), you can aquire (increase the count of the semaphore by 1 if its limit has not been reached yet) it with Semaphore#aquire and release (decrese the count of the semaphore) with Semaphore#release.
Aside from that, it seems like you are developing an Android app. You should never block the main thread of an Android application (or the UI thread of any graphical application) as this will block your UI and result in Application not responding notices. Blocking the UI (thread) means that your app will not respond to any UI events (like the user clivking on a button). If you need to do blocking stuff, you should do that in a background/worker thread. You should also refrain from doing IO operations in the main thread for that reason (android even blocks network operations in the main thread).
You are using the wrong method. You should call await, not wait. See CountDownLatch for example code.
1.The thread should start
2.It should be await and not wait.
Related
I have an activity running, of course, on UI thread and there is another thread running in background and communicating with activity using Handler post method(through looper).
When screen is turned of or application is hidden it continues to work.
So I need to stop this thread in onPause method and wake it up in onResume mehtod.
In my thread I have condition to pause it or to stop.
How to can I put thread to sleep in onPause method. And wake it up after activity is again in foreground.
I can do it with one object using monitor calling wait method and than notify on this object.
But is it good approach ? Or there is another way to do this elegantly.
Sounds like a good place to use a turnstile. Initialize a Semaphore with one permit:
Semaphore turnstile = new Semaphore(1);
Make your background activity periodically pass through the turnstile like so:
turnstile.acquire();
turnstile.release();
When the foreground thread wants the background thread to pause at the turnstile, it can lock the turnstile:
turnstile.acquire();
And when the foreground thread wants that background thread to start working again, it can unlock the turnstile():
turnstile.release();
Good software engineering practice would be to wrap the whole thing up in a Turnstile class with appropriately named methods for the foreground and background threads to call. I'll leave that as an exercise for the reader.
Android suggests using services for long term background tasks, but if you're just opening a new thread that is tied to your Android lifecycle, I don't think it would be bad to use a monitor and call wait/notify. Can you be more specific with what you are doing?
This is an overview of how I would stop and resume a stopped thread. (You may want to implement runnable in yours)
class ThreadDemo extends Thread {
private Object monitor; //This is the monitor
private boolean keepRunning = true;
private Thread t;
ThreadDemo(){
System.out.println("Creating thread");
}
public void callinOnResume(){
synchronized(monitor){
monitor.notify();
}
}
public void callinOnPause(){
try {
synchronized(monitor){
System.out.println(threadName + "Waiting");
monitor.wait();
}
} catch (InterruptedException e) {
System.out.println("Thread interrupted " + e.toString());
}
}
public void run() {
System.out.println("Starting to loop.");
while (keepRunning) {
//stuff
}
System.out.println("Done looping.");
}
public void start ()
{
System.out.println("Starting " + threadName );
if (t == null)
{
t = new Thread (this, threadName);
t.start ();
}
}
}
It is a bad practice to stop/resume a thread outside that thread. The thread must decide itself when to run and when to stop. As a result, the background thread should check periodically if its work is still needed, and the client (foreground) thread should issue some signals about that.
One way to issue signals is to form that signals as jobs of type Runnable and then execute them on a thread pool. So when the activity sleeps, it just does not issue signals.
The main problem when a background thread wants to update the UI is that the target Activity can be closed (or in the process of recreation) and the updating task fails. The AcyncTask class does not solve this problem. A correct solution is published at my Github workspace. But before to use this or another solution, think twice if you really need a background thread. The best way is not to use background thread at all, making all UI updates directly on the UI thread. Of course, if updates are taken from the network, then a background thread must be used.
I create a Thread like the following code. This Thread will send the POST request.(The code is not yet written , so I didn't post the detail code of Thread )
final Runnable Update_Value = new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
**// It will send the POST request to the Server**
}
};
I use the new Thread(Update_Value).start(); to run the Thread.
And I use new Thread(Update_Value).interrupt(); to interrupt the Thread.
1. If I use new Thread(Update_Value).start(); to run the Thread.
2 How to interrupt the Thread when I using new Thread(Update_Value).start(); ?
3 Is the thread close when App close if I didn't close it ?
Sorry about my English...Thanks in advance.
If you use new Thread each time, the two calls create two different threads; they don't act on the same thread.
The interrupt() method does not stop the thread. Rather, it tells the thread to take a look at any interrupt flags that may also have been set, such as a shutdown flag. The thread itself must contain code to check for interrupts and to check for flags such as shutdown flags.
interrupt method is used to send an interrupt signal to a running thread. Calling on a new thread does not make sense.
To properly handle the interrupt signal, your thread code should catch InterruptedException. Something like this:
try {
// do thread task
} catch (InterruptedException e) {
// interrupted: if required do something on interrupt or simply return
return;
}
I am using the Java ExecutorService framework to submit callable tasks for execution.
These tasks communicate with a web service and a web service timeout of 5 mins is applied.
However I've seen that in some cases the timeout is being ignored and thread 'hangs' on an API call - hence, I want to cancel all the tasks that take longer than say, 5 mins.
Currently, I have a list of futures and I iterate through them and call future.get until all tasks are complete. Now, I've seen that the future.get overloaded method takes a timeout and throws a timeout when the task doesnt complete in that window. So I thought of an approach where I do a future.get() with timeout and in case of TimeoutException I do a future.cancel(true) to make sure that this task is interrupted.
My main questions
1. Is the get with a timeout the best way to solve this issue?
2. Is there the possibility that I'm waiting with the get call on a task that hasnt yet been placed on the thread pool(isnt an active worker). In that case I may be terminating a thread that, when it starts may actually complete within the required time limit?
Any suggestions would be deeply appreciated.
Is the get with a timeout the best way to solve this issue?
This will not suffice. For instance, if your task is not designed to response to interruption, it will keep on running or be just blocked
Is there the possibility that I'm waiting with the get call on a task that hasnt yet been placed on the thread pool(isnt an active worker). In that case I may be terminating a thread that, when it starts may actually complete within the required time limit?
Yes, You might end up cancelling as task which is never scheduled to run if your thread-pool is not configured properly
Following code snippet could be one of the way you can make your task responsive to interruption when your task contains Non-interruptible Blocking. Also it does not cancel the task which are not scheduled to run. The idea here is to override interrupt method and close running tasks by say closing sockets, database connections etc. This code is not perfect and you need to make changes as per requirements, handle exceptions etc.
class LongRunningTask extends Thread {
private Socket socket;
private volatile AtomicBoolean atomicBoolean;
public LongRunningTask() {
atomicBoolean = new AtomicBoolean(false);
}
#Override
public void interrupt() {
try {
//clean up any resources, close connections etc.
socket.close();
} catch(Throwable e) {
} finally {
atomicBoolean.compareAndSet(true, false);
//set the interupt status of executing thread.
super.interrupt();
}
}
public boolean isRunning() {
return atomicBoolean.get();
}
#Override
public void run() {
atomicBoolean.compareAndSet(false, true);
//any long running task that might hang..for instance
try {
socket = new Socket("0.0.0.0", 5000);
socket.getInputStream().read();
} catch (UnknownHostException e) {
} catch (IOException e) {
} finally {
}
}
}
//your task caller thread
//map of futures and tasks
Map<Future, LongRunningTask> map = new HashMap<Future, LongRunningTask>();
ArrayList<Future> list = new ArrayList<Future>();
int noOfSubmittedTasks = 0;
for(int i = 0; i < 6; i++) {
LongRunningTask task = new LongRunningTask();
Future f = execService.submit(task);
map.put(f, task);
list.add(f);
noOfSubmittedTasks++;
}
while(noOfSubmittedTasks > 0) {
for(int i=0;i < list.size();i++) {
Future f = list.get(i);
LongRunningTask task = map.get(f);
if (task.isRunning()) {
/*
* This ensures that you process only those tasks which are run once
*/
try {
f.get(5, TimeUnit.MINUTES);
noOfSubmittedTasks--;
} catch (InterruptedException e) {
} catch (ExecutionException e) {
} catch (TimeoutException e) {
//this will call the overridden interrupt method
f.cancel(true);
noOfSubmittedTasks--;
}
}
}
}
execService.shutdown();
Is the get with a timeout the best way to solve this issue?
Yes it is perfectly fine to get(timeout) on a Future object, if the task that the future points to is already executed it will return immediately. If the task is yet to be executed or is being executed then it will wait until timeout and is a good practice.
Is there the possibility that I'm waiting with the get call on a task
that hasnt yet been placed on the thread pool(isnt an active worker)
You get Future object only when you place a task on the thread pool so it is not possible to call get() on a task without placing it on thread pool. Yes there is a possibility that the task has not yet been taken by a free worker.
The approach that you are talking about is ok. But most importantly before setting a threshold on the timeout you need to know what is the perfect value of thread pool size and timiout for your environment. Do a stress testing which will reveal whether the no of worker threads that you configured as part of Threadpool is fine or not. And this may even reduce the timeout value. So this test is most important i feel.
Timeout on get is perfectly fine but you should add to cancel the task if it throws TimeoutException. And if you do the above test properly and set your thread pool size and timeout value to ideal than you may not even need to cancel tasks externally (but you can have this as backup). And yes sometimes in canceling a task you may end up canceling a task which is not yet picked up by the Executor.
You can of course cancel a Task by using
task.cancel(true)
It is perfectly legal. But this will interrupt the thread if it is "RUNNING".
If the thread is waiting to acquire an intrinsic lock then the "interruption" request has no effect other than setting the thread's interrupted status. In this case you cannot do anything to stop it. For the interruption to happen, the thread should come out from the "blocked" state by acquiring the lock it was waiting for (which may take more than 5 mins). This is a limitation of using "intrinsic locking".
However you can use explicit lock classes to solve this problem. You can use "lockInterruptibly" method of the "Lock" interface to achieve this. "lockInterruptibly" will allow the thread to try to acquire a lock while remaining responsive to the interruption. Here is a small example to achieve that:
public void workWithExplicitLock()throws InterruptedException{
Lock lock = new ReentrantLock();
lock.lockInterruptibly()();
try {
// work with shared object state
} finally {
lock.unlock();
}
}
I'm developing a multithreaded application to make connections to external servers - each on separate threads - and will be blocked until there is input. Each of these extends the Thread class. For the sake of explanation, let's call these "connection threads".
All these connection threads are stored in a concurrent hashmap.
Then, I allow RESTful web services method call to cancel any of the threads. (I'm using Grizzly/Jersey, so each call is a thread on its own.)
I retrieve the specific connection thread (from the hashmap) and call the interrupt() method on it.
So, here is the question, within the connection thread, how do I catch the InterruptedException? (I'd like to do something when the connection thread is stopped by an external RESTful command.)
So, here is the question, within the connection thread, how do I catch
the InterruptedException?
You can not. Since if your thread is blocked on a read I/O operation it can not be interrupted. This is because the interrupt just sets a flag to indicate that the thread has been interrupted. But if your thread has been blocked for I/O it will not see the flag.
The proper way for this is to close the underlying socket (that the thread is blocked to), then catch the exception and propagate it up.
So since your connection threads extend Thread do the following:
#Override
public void interrupt(){
try{
socket.close();
}
finally{
super.interrupt();
}
}
This way it is possible to interrupt a thread blocked on the I/O.
Then in your run method do:
#Override
public void run(){
while(!Thread.currentThread().isInterrupted()){
//Do your work
}
}
So in your case don't try to catch an InterruptedException. You can not interrupt the thread blocked on I/O. Just check if your thread has been interrupted and facilitate the interruption by closing the stream.
When you call Thread.interrupt() on some thread, what happens is that 'interruption' flag is set for that thread. Some methods do check this flag (by Thread.interrupted() or Thread.isInterrupted()) and throw InterruptedException, but usually only methods that can block do that. So there is no guarantee that InterruptedException will ever be thrown in interrupted thread. If you don't call any method that throws InterruptedException, there is no point in catching that exception, since it will not be thrown at all. However you can always check if your thread was interrupted by calling Thread.isInterrupted().
the problem it is with blocking.
Hoverer, try this code, maybe it will help you:
try{
yourObject.read();
}catch(InterruptedException ie){
// interrupted by other thread
}
catch(Exception ex){
// io or some other exception happent
}
your read method, should check if there is available buytes at socket for eg, if there are than read it, othervise go to speel mode. When is sleeping than is available the wake up (InterruptedException) at pur socket read ( whatever read have you) it will be blocked. Some API has a value to max waiting, eg 5 sec 60 sec, if nothing o read than it will be next code executed.
class MyReadingObject
{
public read() throws InterruptedException{
while(shouldIread){
if(socket.available() > 0){
byte[] buff = new byte[socket.avaialble()]
socket.read(buff);
return;
}
else{
Thread.currentThread.sleep(whateverMilliseconds);
}
}
}
}
something like that, but with error handling and some design patterns
Calling interrupt() on a thread doesn't stop it, it just switches on the interrupt flag. It's the responsibility of the code to handle the change in the interrupt status of the thread in consideration and act accordingly. If you are performing a blocking operation in that thread, you are pretty much SOL because your thread is "blocking" on the read. Have a look at the answer which I posted here. So basically, unless you are looping over stuff or periodically checking some flags inside that thread, you have no way of breaking out without closing sockets or stuff like that.
One solution here is to "explicitly" expose the underlying connection object and call close() on it, forcing it to throw some sort of exception, which can be then handled in the threaded code. Something like:
class MyAction extends Thread implements Disposable {
public void doStuff() {
try {
byte[] data = this.connection.readFully();
} catch (InterruptedException e) {
// possibly interrupted by forceful connection close
}
#Override
public void dispose() {
this.connection.close();
}
}
// Elsewhere in code
MyAction action = conMap.get("something");
action.dispose();
Use a try-catch like so:
try {
//code
} catch ( InterruptedException e) {
//interrupted
}
I think that should do the trick, you could also keep a boolean variable on whether to exit, so they would check that variable, if it's true, stop
I am running a thread whose main action is to call on a proxy using a blocking function , and wait for it to give it something.
I've used the known pattern of a volatile boolean and the Interruption , but I'm not sure it will work: When I tried to add a catch block for InterruptedException , I get the error:
Unreachable catch block for InterruptedException. This exception is never thrown from the try statement body
So if I'm never going to get anInterruptedException, this means I'll never get out of the blocking action - thus will never stop.
I'm a bit puzzled. Any idea?
public void run() {
Proxy proxy = ProxyFactory.generateProxy();
Source source;
while (!isStopped) {
try {
source = proxy.getPendingSources();
scheduleSource(source);
} catch (Exception e) {
log.error("UnExpected Exception caught while running",e);
}
}
}
public void stop() {
this.isStopped = true;
Thread.currentThread().interrupt();
}
First, you don't really need a separate flag (if you do, use an AtomicBoolean), just check Thread.currentThread().isInterrupted() as your while condition.
Second, your stop method won't work because it won't interrupt the correct thread. If another thread calls stop, the code uses Thread.currentThread() which means the calling thread will be interrupted, not the running one.
Finally, what is the blocking method? Is it scheduleSource()? If that method doesn't throw InterruptedException, you won't be able to catch it.
Try the following:
private final AtomicReference<Thread> currentThread = new AtomicReference<Thread>();
public void run() {
Proxy proxy = ProxyFactory.generateProxy();
Source source;
currentThread.set(Thread.currentThread());
while (!Thread.currentThread().isInterrupted()) {
try {
source = proxy.getPendingSources();
scheduleSource(source);
} catch (Exception e) {
log.error("UnExpected Exception caught while running", e);
}
}
}
public void stop() {
currentThread.get().interrupt();
}
Only a few, well-defined "blocking methods" are interruptible. If a thread is interrupted, a flag is set, but nothing else will happen until the thread reaches one of these well-defined interruption points.
For example, read() and write() calls are interruptible if they are invoked on streams created with a InterruptibleChannel. If a Socket is used as the starting point, calling interrupt() on a Thread blocked in the read has no effect. Note that if a blocking I/O operation is interrupted successfully, the underlying channel is closed.
Another large class of interruptible operations are those thrown by various blocking operations on classes in the java.util.concurrent packages. Of course, the original wait() method is interruptible as well.
Blocking methods can be identified by looking for a throws InterruptedException in their method signatures. They should be well-documented too, to describe any side-effects of interruption.
You can write an interruptible method of your own, but it has to be composed of interruptible lower-level operations itself.
ok, people, don't kill me over this.
I experimented with Thread.stop() for fun, to kick thread out of a blocking action, catch ThreadDeath, keep target thread alive, and move on.
It seems working. The world isn't ending. But I'm just saying. You are responsible for you own doing. Why am I rapping?
You stop method is calling interrupt on the wrong thread. Thread.currentThread() is the thread that is interrupting, not being interrupted.
How are you calling stop from the executing thread?
If you call stop() from another thread, you'll kill it, not the thread running in the try/catch block.