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.
Related
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.
public class ThreadStarvation implements Runnable{
long startTime=System.currentTimeMillis();
Timer t;
class RunnerTask extends TimerTask {
public void run(){
if((System.currentTimeMillis()- startTime)< 100000){
System.out.println(Thread.currentThread().getName()+": in timer task run() method"+" : "+Calendar.getInstance().getTime());
}
else
t.cancel();
}
}
public synchronized void synchronizedTimerMethod(){
try{
Thread.sleep(1000);
t=new Timer();
t.schedule(new RunnerTask(), 0, 2000);
}
catch(InterruptedException ie){}
}
public void run(){
synchronizedTimerMethod();
}
public static void main(String[] args) {
ThreadStarvation ts1=new ThreadStarvation();
Thread t1=new Thread(ts1);
Thread t2=new Thread(ts1);
t1.start();
t2.start();
}
}
Three doubts is there in above program :
1) What I want from this program was that when thread t1 starts, goes to synchronized method synchronizedTimerMethod() will lock object ts1 and should locked it until timer object breached the condition. Hence Thread t2 will unable to gain regular access to shared resources ts1 and is unable to make progress and will go into starvation. But this is not happening. Is it not possible with Timer class ? I am novice to it.
2) When thread t1 starts, it goes to synchronized method synchronizedTimerMethod and the object ts1 will be locked. The object ts1 will not be released until timer object is scheduled till condition is breached. But what is happening thread t1 timer object first scheduled start at that time only Thread t2 enters synchronized method synchronizedTimerMethod. Is object ts1 got released due to Timer run method?
3) Also When both thread breached the condition the task is not cancelled, in particular the program stucks or I think it goes into deadlock. WHY?
I rewritten my code as below :
public class ThreadStarvation implements Runnable{
long startTime=System.currentTimeMillis();
final Timer t=new Timer;
class RunnerTask extends TimerTask {
public void run(){
if((System.currentTimeMillis()- startTime)< 100000){
System.out.println(Thread.currentThread().getName()+": in timer task run() method"+" : "+Calendar.getInstance().getTime());
}
else
t.cancel();
}
}
public synchronized void synchronizedTimerMethod(){
try{
Thread.sleep(1000);
t.schedule(new RunnerTask(), 0, 2000);
}
catch(InterruptedException ie){}
}
public void run(){
synchronizedTimerMethod();
}
public static void main(String[] args) {
ThreadStarvation ts1=new ThreadStarvation();
Thread t1=new Thread(ts1);
Thread t2=new Thread(ts1);
t1.start();
t2.start();
}
}
Now I just want that the task should get stopped. For that I made the Timer object as final. Then also the task don't seem to cancel. Is some more modification is needed ? Please help.
1) If you want to enforce fact that t1 enters before t2, then you can't depend on Timer (or rather time) to ensure this (arbitrary interleaving). You should rewrite as a Monitor with a barrier (condition) that only permits t1 to enter first. Then make t1 never release the lock to starve t2 i.e. prevent your synchronized method from terminating (see here).
What is a monitor and how do I create one?
In concurrency, it is a construct used to synchronize your program and make it more predictable i.e. t1 before t2 as illustrated. In this context, synchronization is based on certain conditions/states being satisfied. These conditions act as "barriers" which either prevent or allow a thread to execute. This is very useful as we can use such barriers to not only make our program mode predictable, but also allow us to guarantee certain desirable properties in concurrency i.e. fairness, avoiding deadlock etc. Hence the importance of monitors.
In Java we can create a monitor by defining a class which contains the barrier conditions as private variables. We then only allow changes to those variables through synchronized methods that first test whether the conditions have been fulfilled (barrier).
A simple example to illustrate based on simplifications to your code:
public class ExampleMonitor implements Runnable{
// Condition for our barrier, note it is private
private boolean t1Entered = false;
public synchronized void synchronizedTimerMethod(){
// Test the barrier (check if conditions hold)
while (!t1Entered && !Thread.currentThread().getName().equals("t1")) {
try {
// Did not pass barrier so wait and release lock
wait();
} catch (Exception e) {
// Handle
}
}
// Thread passed barrier and has acquired the lock and can do what it wants
// Update condition so now anyone can enter/pass the barrier
t1Entered = true;
// If this method never terminates then no other thread can enter because lock is never released
long enterTime = System.currentTimeMillis();
while (true) {
System.out.println(Thread.currentThread().getName());
// Let's allow the method to return and thus release the lock after fixed amount of time
// We can then see that threads other than t1 can now acquire the lock
if (System.currentTimeMillis() - enterTime > 5000) {
break;
}
}
// Notify/wake up any waiting threads
this.notifyAll();
}
public void run(){
synchronizedTimerMethod();
// Thread will now terminate
}
public static void main(String[] args) throws InterruptedException {
ExampleMonitor ts1 = new ExampleMonitor();
Thread t1=new Thread(ts1);
t1.setName("t1");
Thread t2=new Thread(ts1);
t2.setName("t2");
t2.start();
// To illustrate how Monitors can be used to ensure
// ordering despite the order threads start in
Thread.sleep(2000);
t1.start();
}
}
Note: this is just an quick example to illustrate and is not ideal i.e. you should not define a monitor that implements Runnable. You can read more about monitors here. Also I recommend working through following book which I also used.
2) See immibis' thorough answer.
3) From the Java doc:
After the last live reference to a Timer object goes away and all outstanding tasks have completed execution, the timer's task execution thread terminates gracefully (and becomes subject to garbage collection). However, this can take arbitrarily long to occur. By default, the task execution thread does not run as a daemon thread, so it is capable of keeping an application from terminating. If a caller wants to terminate a timer's task execution thread rapidly, the caller should invoke the timer's cancel method.
public synchronized void synchronizedTimerMethod(){
try{
Thread.sleep(1000);
t=new Timer();
t.schedule(new RunnerTask(), 0, 2000);
}
catch(InterruptedException ie){}
}
This doesn't do what you think it does. The synchronized method waits for one second, then schedules a RunnerTask to happen every two seconds, then returns. Note that it does not wait for the RunnerTask to run. ts1 is locked only until synchronizedTimerMethod returns, i.e. for one second.
When the "condition is breached" after 100 seconds, you only cancel one Timer, because of a bug. Notice that synchronizedTimerMethod sets t to a new Timer, and that there is only one variable t. After the first task is scheduled, t is a Timer - call it Timer 1. After the second task is scheduled, t is a different Timer - call it Timer 2. Then when 100 seconds is up, both tasks cancel t, which cancels Timer 2 twice.
I have a main Mina handler thread is processing and in that thread i made another thread and set it to sleep for specified time. Now i want that this inner thread sleep independently without blocking Handler thread.
following is sample code.
public void messageReceived(IoSession session, Object message) throws Exception {
Integer tts = 5000;
Thread sleepThread = new Thread(obj);
sleepThread.sleep(tts);
}
currently it is blocking main Handler thread.
Thread.sleep() is a static method, so calling sleepThread.sleep(tts) is the same as Thread.sleep(tts). Hence your current thread is just sleeping.
You can't cause another thread to sleep by calling a method on its Thread object. At a push, you could set a flag on the object and your thread could check for the presence of that flag and behave accordingly.
try
final int tts = 5000;
Thread sleepThread = new Thread() {
public void run() {
try {
Thread.sleep(tts);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
};
sleepThread.start();
I have created class by implementing runnable interface and then created many threads(nearly 10) in some other class of my project.How to stop some of those threads?
The simplest way is to interrupt() it, which will cause Thread.currentThread().isInterrupted() to return true, and may also throw an InterruptedException under certain circumstances where the Thread is waiting, for example Thread.sleep(), otherThread.join(), object.wait() etc.
Inside the run() method you would need catch that exception and/or regularly check the Thread.currentThread().isInterrupted() value and do something (for example, break out).
Note: Although Thread.interrupted() seems the same as isInterrupted(), it has a nasty side effect: Calling interrupted() clears the interrupted flag, whereas calling isInterrupted() does not.
Other non-interrupting methods involve the use of "stop" (volatile) flags that the running Thread monitors.
How to stop a thread created by implementing runnable interface?
There are many ways that you can stop a thread but all of them take specific code to do so. A typical way to stop a thread is to have a volatile boolean shutdown field that the thread checks every so often:
// set this to true to stop the thread
volatile boolean shutdown = false;
...
public void run() {
while (!shutdown) {
// continue processing
}
}
You can also interrupt the thread which causes sleep(), wait(), and some other methods to throw InterruptedException. You also should test for the thread interrupt flag with something like:
public void run() {
while (!Thread.currentThread().isInterrupted()) {
// continue processing
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// good practice
Thread.currentThread().interrupt();
return;
}
}
}
Note that that interrupting a thread with interrupt() will not necessarily cause it to throw an exception immediately. Only if you are in a method that is interruptible will the InterruptedException be thrown.
If you want to add a shutdown() method to your class which implements Runnable, you should define your own class like:
public class MyRunnable implements Runnable {
private volatile boolean shutdown;
public void run() {
while (!shutdown) {
...
}
}
public void shutdown() {
shutdown = true;
}
}
Stopping the thread in midway using Thread.stop() is not a good practice. More appropriate way is to make the thread return programmatically. Let the Runnable object use a shared variable in the run() method. Whenever you want the thread to stop, use that variable as a flag.
EDIT: Sample code
class MyThread implements Runnable{
private volatile Boolean stop = false;
public void run(){
while(!stop){
//some business logic
}
}
public Boolean getStop() {
return stop;
}
public void setStop(Boolean stop) {
this.stop = stop;
}
}
public class TestStop {
public static void main(String[] args){
MyThread myThread = new MyThread();
Thread th = new Thread(myThread);
th.start();
//Some logic goes there to decide whether to
//stop the thread or not.
//This will compell the thread to stop
myThread.setStop(true);
}
}
If you use ThreadPoolExecutor, and you use submit() method, it will give you a Future back. You can call cancel() on the returned Future to stop your Runnable task.
Stopping (Killing) a thread mid-way is not recommended. The API is actually deprecated.
However, you can get more details including workarounds here: How do you kill a Thread in Java?
Thread.currentThread().isInterrupted() is superbly working. but this
code is only pause the timer.
This code is stop and reset the thread timer.
h1 is handler name.
This code is add on inside your button click listener.
w_h =minutes w_m =milli sec i=counter
i=0;
w_h = 0;
w_m = 0;
textView.setText(String.format("%02d", w_h) + ":" + String.format("%02d", w_m));
hl.removeCallbacksAndMessages(null);
Thread.currentThread().isInterrupted();
}
});
}`
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.