I'm working on an android app which at some point runs a service. That service runs a new thread for a time-consuming operation and waits for a countDownLatch to be zero. After that it runs a second thread for another time-consuming operation (that new thread isn't really necessary now but will be in the near future).
Now...after starting the downloadThread, if I do the waiting as shown below, the main thread AND the downloadThread suspend operations. However, if I wait for the countDownLatch inside the uploadThread everything works fine.
Thread downloadThread = new Thread(new Runnable() {
#Override
public void run() {
downloadFiles(mMediaFileList);
}
});
downloadThread.start();
try {
Log.d("UploadMedia", "Waiting for DownloadMedia to finish");
mCountDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
Thread uploadThread = new Thread(new Runnable() {
#Override
public void run() {
uploadMedia();
}
});
uploadThread.start();
It's not really a problem but isn't it supposed to work both ways? Is there something I'm missing about the .await() functionality?
Cheers!
Edit: FYI, downloadFiles has callbacks which wait for completion or failure of the task. Can it be that those callbacks work on the main thread which is being suspended by the .await()?
It's not evident where your latch gets count down. But it sounds as it happens during uploadMedia(). If so, your main thread gets stale at latch.await() because there is no other controlflow that could count the latch down to zero.
Related
I have two thread, taskThread, a thread with a long-running task, and a timerThread, a recurrent timer every n milliseconds. I am trying to trigger any function call on taskThread from timerThread.
#Override
public Task<List<Schedule>> createTask() {
return new Task<List<Schedule>>() {
#Override
protected List<Schedule> call() throws Exception {
Task currentTask = this;
Thread taskThread = Thread.currentThread(); //Thread-1,Task thread
Timer checker = new Timer();
checker.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
try {
if(currentTask.isDone()) cancel();
System.out.println("Task thread "+taskThread+" is : "+taskThread.getState());
System.out.println("Timer thread" + Thread.currentThread()+" is : "+Thread.currentThread().getState());
taskThread.wait(); //throws IllegalMonitorStateException
Thread.sleep(300);
Thread.currentThread().notifyAll();
} catch (InterruptedException ex){
System.out.println(ex);
}
}
},0,500);
List<Schedule> result = solveMakespan(this); //Blocking call
checker.cancel(); //cancel timer
return result;
}
};
}
The scenario I am trying to achieve, is making the taskThread wait for the timerThread before continuing, I read about synchronized blocks but I am not sure how to make the timer block acquire the lock since the solveMakespan is declared outside its thread, and declaring it inside the timer would make it execute multiple times.
EDIT : Concerning the nuance about "accessing the task's thread", I'd like to either be able to call .wait() or join() on the Thread that I want to wait from the Timer thread, or for the Task instance to provide a method that would run on its existing thread, but triggerable from the timer instance. The code snippet should hopefully make the goal I'm trying to achieve clear.
I have the following code which runs on a simple main activity:
Executor executor = Executors.newFixedThreadPool(1);
executor.execute(new Runnable() {
public void run() {
try {
System.out.println("sleep");
Thread.sleep(5000);
} catch (InterruptedException e) {
System.out.println("Interrupted, so exiting.");
}
}
});
It looks like that when i run this code application doesnt terminate and nothing gets printed either (except the first sleep).
On the other hand when i run this:
Thread t = new Thread(new Runnable() {
public void run() {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
application terminates just fine. Why?
Executor interface would not allow you to shutdown the service. Preferred way is to use ExecutorService instead of Executor
ExecutorService executorService = Executors.newSingleThreadExecutor(factory);
executorService.execute(new Runnable() {
#Override
public void run() {
try {
doTask();
} catch (Exception e) {
logger.error("indexing failed", e);
}
}
});
executorService.shutdown();
Executor thread keeps running after main class is finished
Yep, it's designed to do that. The whole point of an ExecutorService is that there is a pool of threads. Even though the Runnable that you submitted has finished, the threads in the pool are waiting for other jobs to come along. You need to shutdown the pool to get your application to terminate.
It looks like that when i run this code the application doesn't terminate and nothing gets printed either (except the first sleep).
The right way to use the ExecutorService is something like the following:
ExecutorService threadPool = Executors.newFixedThreadPool(1);
threadPool.submit(new Runnable() ...);
// submit any other jobs to the pool here
...
// after last submit, you shutdown the pool, submitted jobs will continue to run
threadPool.shutdown();
// optionally wait for all jobs to finish in pool, similar to thread.join()
threadPool.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
Once you shutdown the pool and the jobs that have submitted finish, the threads in the pool will terminate and, if there are no more non-daemon threads, your application will stop.
Thread t = new Thread(new Runnable() {
public void run() {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
With this, the thread will terminate after executing the run method.
Runnbale r = ...
Executor executor = Executors.newFixedThreadPool(1);
executor.execute(r);
With this, the executor will create a thread which works like below:
new Thread(new Runnable() {
#Override
public void run() {
while(notShutdown()) {
waitingForTask(); // may get blocked
runTask(); // execute Runnable user submits
}
}
});
This thread will not terminate after the first task, it will keep waiting for new tasks. You need call executor.shutdown() explicitly.
Cause
: You did not shutdown the executor .And When you do the shutdown be aware to do it after it's termination
Solution
: shut it down only after its termination using a simple code.
For example :
executor.shutdown();
while (!executor.isTerminated()) {}
Another solution is to use ExecutorCompletionService if you want to take tasks as they complete you need an ExecutorCompletionService. This acts as a BlockingQueue that will allow you to poll for tasks as and when they finish.
Recently I am working on a piece of code involving synchronization and struggling on how to test it. To get into the problem, we can consider we are writing a unit test for a CountDownLatch:
CountDownLatch l = new CountDownLatch(1);
new Thread() {
#Override
void run() {
l.await();
System.out.println("good!");
}
}.start();
Thread.sleep(1000); // wait for thread to run
if (the thread is alive)
l.countDown();
else
System.out.println("bad!");
So the problem is, there is no guarantee that the sleep for 1 second would be enough in all cases in all machines. So my goal is to eliminate this type of sleeping code to expect a certain state when testing synchronization, but soon realize it starts to become halting problem.
My current solution would be to query the state of the thread:
Thread t = ...
t.start();
if (t.getState() == Thread.State.WAITING) {
l.countDown();
assert(t.getState() == Thread.State.RUNNABLE); // or running or terminated
}
my questions are:
would that work? i.e. would the state of the thread will be toggled atomically at the moment, in this case, a count down latch reach a wakeup condition?(the doc says nothing about the change timing of the state)
do you have better suggestions?
Looking into your example I have a feeling that you're using countdown latch upside-down. Why can't you do something like that:
#Test
public void testThreads() throws Exception {
CountDownLatch l = new CountDownLatch(1);
new Thread(new Runnable() {
#Override
public void run() {
System.out.println("Parallel thread is doing something.");
try {
// instead of this sleep you put your logic that you want to be executed.
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
l.countDown();
}
}).start();
System.out.println("Main thread is waiting for parallel thread");
l.await();
System.out.println("Done.");
}
Please, correct me if I misunderstand your problem.
But generally speaking, I agree with one of the comments below your post that you should probably not test multithreading with unit tests.
I'm using GCM to receive message from google server. when the message has received at device ; it starts a 1-minute thread, and if no other message has come until 1min it will show the analog clock on screen. but if before 1 minute the message has come: here's the problem how can reinitialise the thread from zero to measure again 1min???
Thread t = new Thread(new Runnable() {
#Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
}
handler.post(new Runnable() {
#Override
public void run() {
analogClock.setVisibility(View.VISIBLE);
lblMessage.setText("");
}
});
}
});
t.start ();
// Schedule task to terminate thread in 1 minute
ScheduledExecutorService exec = Executors.newSingleThreadScheduledExecutor();
exec.schedule (
new Runnable(){
#Override
public void run (){
t.interrupt();
}
} , 1, TimeUnit.MINUTES);
}
Simplest solution seems to be to keep a rest boolean in the thread - when you scheduled runnable executes you can either terminate the thread or reschedule this runnable for a new minute in the future.
You can't exactly reuse a thread in Java but you can plan NOT to terminate your thread unless it is appropriate.
In Java you really can't reuse threads (see here). Just create another one.
To cancel previous task you can cancel the ScheduledFuture using cancel(boolean):
ScheduledFuture<?> future = exec.schedule (
new Runnable(){
#Override
public void run (){
t.interrupt();
}
} , 1, TimeUnit.MINUTES);
}
...
future.cancel(true); // Or false, I don't know your exact requirements here
Anyway in your case and in Android you're better off with AsyncTask instead of Thread.
I have this piece of code:
Timeout s = new Timeout();
Timer timer = new Timer();
timer.schedule(s, 1000L); // fires after 1 second
How can I launch the following piece of code as a thread by itself? Would I need to pass the timer and Timeout to a Runnable and then start it? What happens if the thread's Run() ends before the timer is fired?
I am thinking of doing this instead:
ScheduledExecutorService ses = Executors.newScheduledThreadPool(1);
Timeout s = new Timeout(); // Timeout is a runnable
ses.schedule(s, 10, TimeUnit.SECONDS);
but how do I exit the thread after the timeout? I run out of thread after a while
Thanks
I'm not exactly sure what you're asking, but I'll give it a shot.
How can I launch the following piece of code as a thread by itself?
In short...
Timeout.java
public class Timeout extends TimerTask {
boolean isDone = false;
#Override
public void run() {
// TODO something
synchronized(this) {
isDone=true;
this.notifyAll();
}
}
public synchronized void join() throws InterruptedException {
while(!this.isDone)
this.wait();
}
}
TimeoutRunner.java
public class TimerRunner implements Runnable {
#Override
public void run() {
Timeout timeout = new Timeout();
Timer timer = new Timer();
timer.schedule(timeout, 1000L);
try {
timeout.join();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
timer.cancel();
}
}
}
Run the TimeoutRunner using:
new Thread(new TimeoutRunner()).start();
The join method will block the thread until the timeout task has completed execution. At that time you can close the Timer. This is, however, a lot of thread creation, and IMO bad programming.
When you create a Timer instance, a thread is created to execute the Timeout#run() method. The timer has it's own run method that blocks until your task is ready for execution. After the given timeout period elapses, the timer unblocks and executes your timeout.
Your TimeoutRunner thread will block until the timeout operation completes. Only then can this thread die.
The Timer class is very limited. You need to create a new instance for every task. In my option, the ScheduledExecutorService is a better option. Keep the ScheduledExecutorService open for as long as you plan on executing tasks. If you need something like a scheduled cached thread pool, feel free to use this class from one of my open-source projects (Scheduler). This works great with a cached thread pool.