I am dealing with threads and I want to run this code whenever I open Cal_JInternalFrame. It runs the fist time, but whenever I reopen the frame, it doesn't run again. I use t1.interrupted() at exit time of the whole application. The code is:
Thread t1 = new Thread( new Runnable() {
#Override
public void run() {
while ( !t1.isInterrupted() ) {
// ......... Oil Calculation Thread ...
int price = (Integer.parseInt(jLabel22.getText()));
int qty = (Integer)jSpinner8.getValue();
int totalOil =qty * price;
jTextField19.setText(String.valueOf(totalOil));
}
}
});
t1.start() is in the constructor of the main frame.
The thread primitive methods destroy(), stop(), resume(), and suspend() have been deprecated, so I can't use those. How can I stop and resume a thread now? And if my thread t1 is interrupted, how can it be resumed or run again?
Threads cannot be re-used. For tasks that require to be executed on a separate thread at different times, use a single thread executor.
It seems like you need a worker thread. Since standard threads are not reusable without extra work, we use worker threads to manage tasks that should be executed multiple times.
ExecutorService executors = Executors.newSingleThreadExecutor();
With this, you can reuse a single thread to execute code multiple times. It also allows you to make asynchronous callbacks using Future like this:
class Demo {
static ExecutorService executor = Executors.newSingleThreadExecutor();
public static void main(String[] args) {
Future<String> result = executor.submit(new Callable<String>() {
public String call() {
//do something
return "Task Complete";
}
});
try {
System.out.println(result.get()); //get() blocks until call() returns with its value
}catch(Exception e) {
e.printStackTrace();
}
}
}
You can now re-use executor for the task that you want. It accepts Runnable through it's execute(Runnable) method.
I see you're using Swing. Post all swing code to the Event Dispatch Thread using EventQueue.invokeLater(Runnable). getText() and setText() should be called on the Event Dispatch Thread to avoid inconsistancies.
How can I stop and resume a thread now?
You can't. Instead, you need to make your thread stop and resume itself. For example:
private boolean wake;
public synchronized void wakeup() {
this.wake = true;
this.notify();
}
public void run() {
while ( !t1.isInterrupted() ) {
// do stuff ...
wake = false;
synchronized (this) {
while (!wake) {
try {
this.wait();
} catch (InterruptedException ex) {
t1.interrupt(); // reset the interrupted flag
}
}
}
}
}
When some other thread wants to get this one to do something, the calls the wakeup() method on the extended runnable object.
And if my thread t1 is interrupted, how can it be resumed or run again?
As you have written it, No. Once the thread returns from the run() method call, it cannot be restarted. You would need to create and start a brand new Thread.
However, what you are trying to do is unsafe. As #Erwin points out, it is not safe for the t1 thread to be calling methods on Swing objects such as jTextField19. You should only call methods on Swing objects from the Swing event dispatching thread.
Reference:
Concurrency in Swing
Related
I have a thread which executes code periodically, e. g. every 10 seconds. I'd like to have the option to also invoke the same code in a spontaneous way and not have to wait 10 seconds. But the code of the automatic and spontaneous execution must never run concurrently, instead they should run in sequence if the user presses the execute button while the thread is invoking the same method.
Does anyone know a good pattern or even a class that can address this kind of requirement?
First thing that comes to mind would be to make the work method synchronized. But in that case the manual execution (e. g. button press) is blocked and has to wait until the method in the thread is finished. Is there a better approach without blocking?
Example:
public class Executor extends Thread {
// endless loop, executes work method periodically with pause inbetween
#Override
public void run() {
while( true) {
work( "automatic");
pause(10000);
}
}
// Working method that's executed periodically or manually
private synchronized void work( String text) {
System.out.println( "Working " + text + " " + System.currentTimeMillis());
}
// helper method that pauses the thread
private static void pause( long sleepMs) {
try {
Thread.sleep(sleepMs);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
// start automatic execution
Executor executor = new Executor();
executor.start();
// pause a while
pause(1000);
// manual execution
executor.work( "manual");
}
}
Edit: Solution for my requirement:
public class ScheduledExecutor {
public static void main(String[] args) throws InterruptedException {
ScheduledThreadPoolExecutor executor = (ScheduledThreadPoolExecutor) Executors.newScheduledThreadPool(1);
executor.scheduleWithFixedDelay(new Work("auto"), 0, 10, TimeUnit.SECONDS);
Thread.sleep(1000);
executor.execute(new Work("manual"));
}
public static class Work implements Runnable {
String text;
public Work(String text) {
this.text = text;
}
#Override
public void run() {
System.out.println("Working " + text + " " + System.currentTimeMillis());
}
}
}
I would create a new, single-thread executor service:
ExecutorService executorService = Executors.newFixedThreadPool(1);
Then, I would set up a timer that feeds the executorService a task once every 10 seconds.
new Timer(10000, new ActionListener {
public void actionPerformed(ActionEvent evt) {
executorService.execute(() -> doWhatever());
}
}).start();
Finally, you can call executorService.execute(() -> doWhatever()); in your button press handler, or wherever else you want in your code.
Only one activation of doWhatever() will run at a time because the executorService has only one thread on which to run them. And, your button press handler will never have to wait, because it does nothing but put a new object on a queue.
I have a thread which executes code periodically, e. g. every 10 seconds. I'd like to have the option to also invoke the same code in a spontaneous way and not have to wait 10 seconds.
A simple way to do this in your code is not to pause by using Thread.sleep(...) but rather do wait(...). Then whenever you want the command to wakeup and run manually it just does a notify().
So you code would look something like:
while( true) {
work( "automatic");
synchronized (this) {
try {
// wait for a bit but allow someone else to awake us to run manually
wait(10000);
} catch (InterruptedException ie) {
// always a good pattern
Thread.currentThread().interrupt();
return;
}
}
}
Then when you want to have it run manually you do:
synchronized (executor) {
executor.notify();
}
The notify will awaken the thread immediately so that it can run it's task. The work method then does not need to be synchronized because only the Executor thread is running it.
NOTE: As pointed out by #shinobi, using wait() like this could suffer from spurious wake-ups which can happen with certain OS thread implementations.
Lastly, it is a better practice to make Executor implement Runnable as opposed to extending Thread.
Share a semaphore between the server thread (the one that executes the task) and client threads (the ones that need to trigger immediate execution):
Semaphore sem = new Semaphore( 0 );
The server thread needs to execute the following code (note that it's an endless loop — you'll likely want to plug-in your program termination check as the condition to while()):
while( true ) {
try {
sem.tryAcquire( 10, TimeUnit.SECONDS );
} catch( InterruptedException e ) {
continue;
}
runTask();
sem.drainPermits();
}
Then, in order to trigger immediate execution, the client thread needs to do:
sem.release();
Thus, the server thread will execute the task upon either acquiring a permit from the semaphore as soon as a client thread releases one (triggered immediate execution,) or timing-out in Semaphore.tryAcquire() (periodic executions 10s apart, end-to-start.) Having executions 10s apart start-to-start will take some slightly more involved logic, as well as keeping track of last execution's starting time, but the basic idea remains the same.
You need to drain the permits each time in order to avoid multiple back-to-back executions of the task, in cases where it might be triggered for immediate execution while still being executed.
I am using Threads (still..) for many stuff right now. I found many methods of thread that I would most likely use marked as deprecated.
Is there any chance to pause/resume thread with some triggers? Most people say to use wait.. but if I don't know the time ? I have some events that can happen after 5 minutes or after 2 hours...
Also .. another thing.
If I have a Thread .. it has an run() method. Now the Thread is started , run does what it has to do and then the Thread dies. Like forever ? The stuff from run() method is done so the Thread is ready to be taken out by garbage collector or is it just in some phase of disabled but still existing ?
Now you have a run method like that :
public void run(){
while(running){
//do stuff...
}
}
If I switch the running to false, run method loops and stops because there is nothing more to do . Does this thread also die ? Can I for example say after some time I want to rerun this thread, so I just set the running to true again and call the run method, or do I have to recreate the Thread once again ?
A Thread can only "live" once. When you create a Thread, you specify a Runnable instance as a target (if you don't, the thread targets itself—it implements Runnable and its default run() method does nothing). In either case, when the thread completes the run() method of its target Runnable, the thread dies.
In the example posed in the question, setting running to true after the run() method has returned will do nothing; the Thread can't be restarted after dying.
If you want to pause a thread, and reuse it later, there are a number of mechanisms. The most primitive is wait() and notify(). Rather than waiting for a specified period of time, you wait until a condition changes, like this:
abstract class Pausable implements Runnable {
private final Object lock = new Object();
private boolean pause = false;
abstract void doSomething();
#Override
public void run() {
while (cantering()) doSomething();
}
private boolean cantering() {
synchronized (lock) {
while (pause) {
try { lock.wait(); }
catch (InterruptedException ex) {
Thread.currentThread().interrupt();
return false;
}
}
}
return true;
}
final void whoa() {
synchronized(lock) {
pause = true;
}
}
final void giddyup() {
synchronized(lock) {
pause = false;
lock.notify();
}
}
}
That's a lot of code, and it's fragile. I've been writing Java for 20 years and I'm not sure I got it right. That's why you should use the right tool from java.util.concurrency. For example, if you are waking up the thread to process a message, use a BlockingQueue, and let the consuming thread wait for messages to arrive on the queue. If you have tasks you want to perform asynchronously in response to some event, create an ExecutorService and submit the tasks. Even if you do want to use something like wait()/notify(), the concurrency package's Condition class gives you a lot more control over locking than intrinsic locks offer.
Can I [...] and call the run method?
If you have a Thread t = ...;, and you write a call to t.run(), you probably are making a mistake.
A Thread is not a thread. A thread is a path of execution through your code. A Thread is an object with methods that can be used to create a new thread and manage its life-cycle.
You create the new thread by calling t.start().
Remember this mantra:
The start() method is the method that the library provides for your code to call when you want to start a new thread.
The run() method is the method that your code provides for the library to call in the new thread.
I'm actually in need of waiting for the ui thread to execute a runnable before my application thread can continue. Is the wait()/notify() way a proper way to do it or is there something better for this? What I'm actually doing looks like this:
public void showVideoView() {
try {
final AtomicBoolean done = new AtomicBoolean(false);
final Runnable task = new Runnable() {
#Override
public void run() {
synchronized(this) {
mStartupCurtain.setVisibility(View.GONE);
mVideoView.setVisibility(View.VISIBLE);
mWebView.loadUrl("about:blank");
mWebView.setVisibility(View.GONE);
done.set(true);
notify();
}
}
};
mUiHandler.post(task);
synchronized(task) {
while(!done.get()) {
task.wait();
}
Log.d(TAG, "showVideoView done!");
}
} catch (InterruptedException e) {
Log.e(TAG, "Thread got interrupted while waiting for posted runnable to finish its task");
}
}
Also when I do this I have to be sure that the thread is not the one of the UI, which happens when I start calling methods from a listener method coming from an interface like MediaPlayer.OnCompletionListener.
What do you think?
Looks fine to me.
The "done" variable could be a regular Boolean instead of AtomicBoolean since you definitively get/set it's value within the lock. I like that you check the value of "done" prior to calling wait - since it is quite possible the task will have been completed before you ever enter the lock in the worker thread. If you had not done that, the wait() call would go indefinitely since the notify() had already happened.
There is one edge case to consider that may or may not be applicable to your design. What happens if the UI thread is attempting to exit (i.e. app exit) when the worker thread is still stuck waiting for the task to complete? Another variation is when the worker thread is waiting on the task to complete, but the UI thread is waiting on the worker thread to exit. The latter could be solved with another Boolean variable by which the UI thread signals the worker thread to exit. These issues may or may not be relevant - depending on how the UI is managing the thread to begin with.
Use AsyncTask!
AsyncTask enables proper and easy use of the UI thread. This class
allows to perform background operations and publish results on the UI
thread without having to manipulate threads and/or handlers.
http://developer.android.com/reference/android/os/AsyncTask.html
Function:
public static void postOnUI(Runnable runnable,boolean wait) {
if (Looper.getMainLooper().getThread() == Thread.currentThread()) {
// Is on UI thread.
runnable.run();
return;
}
Handler uiHandler = new Handler(Looper.getMainLooper());
AtomicBoolean done = new AtomicBoolean(false);
uiHandler.post(() -> {
runnable.run();
done.set(true);
});
if (wait) {
while (!done.get()) {
try {
Thread.sleep(20);
} catch (InterruptedException e) {
}
}
}
}
Usage Example:
Utils.postOnUI(headerView::updateUI,true);
I'm writing an application that spawns multiple concurrent tasks. I'm using a thread pool to implement that.
It may happen that an event occurs that renders the computations being done in the tasks invalid. In that case, I would like to stop the currently running tasks, and start new ones.
My problem: How do I stop the currently running tasks? The solution I implemented is to store a reference to the task thread and call interrupt() on this thread. In demo code:
public class Task implements Runnable {
private String name;
private Thread runThread;
public Task(String name) {
super();
this.name = name;
}
#Override
public void run() {
runThread = Thread.currentThread();
System.out.println("Starting thread " + name);
while (true) {
try {
Thread.sleep(4000);
System.out.println("Hello from thread " + name);
} catch (InterruptedException e) {
// We've been interrupted: no more messages.
return;
}
}
}
public void stop() {
runThread.interrupt();
}
public String getName() {
return name;
}
}
And the main method is:
public static void main(String args[]) {
executorService = Executors.newFixedThreadPool(2);
Task t1 = new Task("Task1");
Task t2 = new Task("Task2");
executorService.execute(t1);
executorService.execute(t2);
executorService.execute(new Task("Task3"));
executorService.execute(new Task("Task4"));
try {
Thread.sleep(12000);
t1.stop();
System.err.println("Stopped thread " + t1.getName());
Thread.sleep(8000);
t2.stop();
System.err.println("Stopped thread " + t2.getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Is this a good solution, or is there a better way to stop a running thread in a thread pool?
You can stop it by holding a reference to that future
Future<?> future = exec.submit( new Runnable() {
while (true){
try{
obj.wait();
} catch(InterruptedException e){
System.out.println("interrupted");
return;
}
}
});
future.cancel(true);
boolean is for - may interrupt if running.
I tested out and got an interrupted exception from that thread.
If you have cachedThreadPool you may want to double check that you catch the exception in your runnable, and then don't set back the flag interrupted, because your thread will run another future, if you set interrupt, the other queue future may not run.
The idea behind your approach is one of the several correct solutions. Dealing with InterruptedException gives a great rundown on how you should use the interrupt mechanism. This mechanism is mainly useful when you are long computations. One other thing to keep in mind is that it is possible for other libraries to spoil your interrupt mechanism by not doing what the guide says (not resetting the interrupt state when they haven't handled it etc).
Do note that your Task class isn't thread-safe. You could be stopping the task before saving the currentThread, which would give a NullPointerException.
A much simpler approach is to set a volatile boolean variable running and instead of a while(true) loop doing a while(running) approach (this is however much more general).
Another thing to look at is the FutureTask mechanism, as this already has a canceling mechanism that uses the interrupt mechanism.
In your overridden run() method you loop forever with while(true). The standard behaviour would be to have a boolean runIndicator which the run() method sets to true when it starts, and your loop should then be while(runIndicator). Your stop() method should simple set runIndicator = false so the next iteration of the loop will fall out.
executorService.shutdown() and executorService.shutdownNow() should be used to shutdown the thread pool to gracefully exiting the application. See ExecutorService.
See Qwerky's answer for ending the currently running thread.
This code creates and starts a thread:
new Thread() {
#Override
public void run() {
try { player.play(); }
catch ( Exception e ) { System.out.println(e); }
}
}.start();
I'd like to modify this code so that the thread only starts if there are no other threads open at the time! If there are I'd like to close them, and start this one.
You can create an ExecutorService that only allows a single thread with the Executors.newSingleThreadExecutor method. Once you get the single thread executor, you can call execute with a Runnable parameter:
Executor executor = Executors.newSingleThreadExecutor();
executor.execute(new Runnable() { public void run() { /* do something */ } });
My preferred method would be putting a synchronized keyword on the play method
synchronized play()
synchronized methods will lock the function so only one thread will be allowed to execute them at a time.
Here's some more info
https://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html
you could create a static data member for the class(where threading takes place) which is incremented each time an object of that class is called,read that and u get the number of threads started