I'm writing an application using JavaFX and my understanding is that, while the UI runs in a thread, all other non-UI operations must run in another. So far, all examples I've found are variations of the following:
myButton.setOnAction(new EventHandler<ActionEvent>(){
#Override
public void handle(ActionEvent a) {
// Some UI operations
new Thread() {
public void run() {
// Some non-UI operations
Platform.runLater(new Runnable() {
public void run() {
// Some operations to update the UI
}
});
}
}.start();
}
});
My question is: do you need to somehow kill the thread in order to release its resources? In the examples I've never nobody seems to use Thread.join or any other similar method.
Also, would it be advisable to use setDaemon like this?
myButton.setOnAction(new EventHandler<ActionEvent>(){
#Override
public void handle(ActionEvent a) {
// Some UI operations
final Thread child = new Thread() {
public void run() {
// Some non-UI operations
Platform.runLater(new Runnable() {
public void run() {
// Some operations to update the UI
}
});
}
};
child.setDaemon(true);
child.start();
}
});
Note:
According to this thread (JavaFX multithreading - joining threads won't update the UI) Thread.join must not be used, but it doesn't seem to address the question of what happens to the threads that are no longer needed or how to kill them.
Threads will age out when there is nothing scheduled for them. However, it is not a good practice to depend on that, as it can take up resources.
The better approach is to use an ExecutorService, such as described in the documentation. A ThreadPoolExecutor can run one or more threads. You can use the same executor to keep submitting runnable tasks, and they will be executed on the threads that it manages. The documentation gives examples on how to shut down the executor service at the end of your application. If you are confident that you have no outstanding tasks being executed, you can issue shutdownNow() to immediately clean up all the threads.
Related
Threads add a lot of verbal to the code and make it harder to understand and reason about. Look at this code for example:
public class ConnectionListener implements Runnable {
private Thread thread;
private boolean running;
public void start() {
if (!running) {
thread = new Thread(this);
thread.start();
}
}
public void stop() {
if (running) {
running = false;
thread.interrupt();
}
}
#Override
public void run() {
running = true;
while (running) {
// Do some crap
}
}
}
The whole concern of this class should be listening for connection requests from the network. But look how many lines of code are added just for managing a thread. Is there any way to make this code cleaner?! I don't want to see the thread = new Thread();, not the thread variable and not any of the stop()/start() methods!
Of course I know what the ExecutorService is... But what if I want to manage a long-running thread? By long-running thread, I mean a thread with a life cycle long as the application's life cycle.
Do you have any good solution for me? A way to remove the thread creation and management concerns from a class without making the class extend another class?
I solved the problem by using a single-threaded executor service. I've also read about the performance differences between Plain Thread, ThreadPool and SingleThreadExecutor - SingleThreadExecutor VS plain thread.
Using a single thread executor allows me to start a single thread and manage it using its Future. See code example:
public void func(String[] args) {
ExecutorService es = Executors.newSingleThreadExecutor();
Future<?> f = es.submit(Some Runnable);
}
Thanks to #BasilBourque that gave me this solution in the comments.
I came across this suggestion to combine operations by using the underlying channel's EventLoop to execute them together. In the example provided, write operations are used. It was my assumption was that write operations were already done asynchronously on an I/O thread (the EventLoop?) provided by Netty... so why is it necessary to execute multiple operations using the EventLoop the channel is assigned to?
Also, if doing operations on the EventLoop thread provides some sort of performance benefit then why does that only apply to multiple operations and not single ones?
Any clarification would be appreciated! Thanks.
As I understand when you call this code outside of EventLoop:
channel.write(msg1);
channel.writeAndFlush(msg3);
It under the hood transforms to:
channel.eventLoop().execute(new Runnable() {
#Override
public void run() {
channel.write(msg1);
}
});
channel.eventLoop().execute(new Runnable() {
#Override
public void run() {
channel.writeAndFlush(msg3);
}
});
So for reducing dispatching overhead it is better to combine them to one:
channel.eventLoop().execute(new Runnable() {
#Override
public void run() {
channel.write(msg1);
channel.writeAndFlush(msg3);
}
});
I have a activity and I have to update the Views (like Images) every second. I tried a few different methods which I found to implement the same thing. But which of the method is most efficient and reduces memory leak?
Here are the different methods -
Method 1
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
//DO SOMETHING
handler.postDelayed(this, 1000);
}
}, 1000);
Method 2
ScheduledExecutorService scheduleTaskExecutor = Executors.newScheduledThreadPool(5);
scheduleTaskExecutor.scheduleAtFixedRate(new Runnable() {
public void run() {
//DO SOMETHING
}
}, 0, 1, TimeUnit.SECONDS);
Method 3
Timer myTimer = new Timer();
myTimer.schedule(new TimerTask() {
#Override
public void run() {
//DO SOMETHING
}
}, 0, 1000);
Which one should I use? I am asking this question because I'm updating my GUI in very short interval of time.
If you want to update values or images on your screen you should use the first method. I solved the same issue by using first method.
Method 1
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
//DO SOMETHING
handler.postDelayed(this, 1000);
}
}, 1000);
Alternative
Thread t = new Thread() {
#Override
public void run() {
try {
while (!isInterrupted()) {
Thread.sleep(1000);
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
//update here (images or other values)
}
});
}
} catch (InterruptedException e) {
}
}
};
Context
Take into account the fact the Android uses it's own implementation of java.
There is no Java Virtual Machine in the Android platform. Java
bytecode is not executed. Instead Java classes are compiled into a
proprietary bytecode format and run on Dalvik, a specialized virtual
machine (VM) designed specifically for Android. Unlike Java VMs, which
are stack machines, the Dalvik VM is a register-based architecture.
Comparison of Java and Android API
So what holds true for the java virtual machine may not necessarily reflect on Android's implementation.
As a rule of thumbs it's better to use whatever the Android API makes available.
Solution
I recommend using the Handler.
Especially if you want to update views.
Even the official Android tutorials recommends :
To move data from a background thread to the UI thread, use a Handler
that's running on the UI thread.
From the start Timer gets excluded.
There are some disadvantages of using Timer It creates only single
thread to execute the tasks and if a task takes too long to run, other
tasks suffer. It does not handle exceptions thrown by tasks and thread
just terminates, which affects other scheduled tasks and they are
never run
From this answer.
And from the Android docs:
A ThreadPoolExecutor (i.e. ScheduledThreadPoolExecutor) is preferable to Timer when multiple worker threads are needed, or when
the additional flexibility or capabilities of ThreadPoolExecutor
(which this class extends) are required.
When using the Handler i recommend reading through this tutorial if you want to avoid memory leaks.
If it wasn't the case of an UI update a ThreadPoolExecutor would have been better because they provide improved performance when executing large numbers of asynchronous tasks, due to reduced per-task invocation overhead.
I need to call the same thread multiple times in my app. Using my original code, the first time is can be executed just fine. But the second time it crashes - I then learned that each thread shall only be executed not more than one time.
My original piece of code:
View.OnClickListener myClickListener = new View.OnClickListener() {
#Override
public void onClick(View v) {
mythread.start();
}
};
Thread mythread = new Thread(){
#Override
public void run() {
runOnUiThread(new Runnable() {
public void run() {
demoBt.setText("Running...");
}
});
try {
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
runOnUiThread(new Runnable() {
public void run() {
demoBt.setText("Finished...");
}
});
}
};
So as I said, it crashes if I try to run it for the second time. So I tried modifying it like:
View.OnClickListener myClickListener = new View.OnClickListener() {
#Override
public void onClick(View v) {
test();
}
};
private void test(){
Thread mythread = new Thread(){
#Override
public void run() {
runOnUiThread(new Runnable() {
public void run() {
demoBt.setText("Running...");
}
});
try {
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
runOnUiThread(new Runnable() {
public void run() {
demoBt.setText("Finished...");
}
});
}
};
mythread.start();
}
It works very good; but my question is that whether this is the correct way to do this action or there is a more optimal way to do this?
Also, is it an acceptable thing to call a thread from insider of another thread? (like the way I put stuff on UI Thread inside the new thread of mine)
EDIT:
This is just an example. For my actual code I have heavy math-based simulation to be done which takes 10sec to be done. Based on the results that will be shown to the user , they may want to change their input parameters and let the simulation run again. This will happen several times.
In addition to the other good answers about using AsyncTask or runOnUiThread(), you could define a private member as a Runnable, like this:
private Runnable mytask = new Runnable() {
#Override
public void run() {
runOnUiThread(new Runnable() {
public void run() {
demoBt.setText("Running...");
}
});
try {
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
runOnUiThread(new Runnable() {
public void run() {
demoBt.setText("Finished...");
}
});
}
};
Then, whenever you want to run it, do
new Thread(mytask).start();
There is nothing bad with that but I think a better way would be using AsyncTask. It is exactly designed for this cases.
You can use AsyncTask multiple times just creating a new one like this new MyAsyncTask().execute(""); (source from here)
Also, is it an acceptable thing to call a thread from insider of another thread? (like the way I put stuff on UI Thread inside the new thread of mine)
runOnUiThread exists solely for that purpose. But there are usually much better ways (e.g. AsyncTask) so using this method is probably a bad idea.
my question is that whether this is the correct way to do this action or there is a more optimal way to do this?
You should not use a thread just to schedule future tasks. They are useful to execute something in parallel to the main thread but add lots of potential errors (try rotating the screen between it prints running..finished, could crash)
I would use a CountDownTimer in your case.
Or a Handler, examples e.g. here: Schedule task in android
From the provided code I assume that you want to perform an UI operation before and after your long mathematical computation. In such as #Andres suggested, AsyncTask is your best buy. It provides method onPreExecute, onPostExecute which runs on UI thread, and thus no need for explicitly calling runOnUiThread.
Key concepts :
You can't start an already started thread. This will return in an IllegalStateException. If you need to perform same task again, you should create a new instance.
If you find yourself creating several instances of a thread (even AsyncTask), since you need to run same task again and again, I would suggest you to use Thread Pool or simple Java Executor Service. Create a singleThread or may be pool and post your runnable onto executorService and it will take care of the rest.
Inter-Thread or Inter-Process communication is quite common requirement.
I have some code which executes a download in a separate thread, created so that the JFrame GUI will continue to update during the download. But, the purpose is completely defeated when I use Thread.join(), as it causes the GUI to stop updating. I need a way to wait for the thread to finish and still update the GUI.
You can have the task that does the download also fire an event to the GUI.
For example:
Runnable task = new Runnable() {
public void run() {
// do your download
SwingUtilities.invokeLater(new Runnable() {
public void run() {
// call some method to tell the GUI that the download finished.
}
});
}
};
and then to run it, either use an Executor (preferred method) or a raw thread:
executor.execute(task);
or
new Thread(task).start();
As pointed out in the comments, you'd generally use a SwingWorker to do this kind of thing but you can also do the manual approach outlined above.
SwingWorker provides a doInBackground method where you would stick your download logic in, a done method where you would stick in code to notify the GUI that the download finished and a get method to get the result of doInBackground (if there was one).
E.g.,
class Downloader extends SwingWorker<Object, Object> {
#Override
public Object doInBackground() {
return doDownload();
}
#Override
protected void done() {
try {
frame.downloadDone(get());
} catch (Exception ignore) {
}
}
}
(new Downloader()).execute();