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.
I am using Runnable to do some background task in my android application. The runnable after completing the background task will call a callback which is implemented by caller of the function which implemented runnable. Now i want to handover execution to main thread once the callback is called.
public void DoInBackground(Callback callback)
{
Thread thread = new Thread(new Runnable(){
//Execution that to be done in background
//calling callback once the result is obtained
});
thread.start()
}
public void callee(){
DoInBackground(new callback(){
#Override
public void onSuccess(int value){
//Do operations after completion of background task
}
});
}
I want the onSucess to run on the main thread rather than the new runnable created in DoInBackground function.
I know it can be done with async task. Is there any other way to do it.
you can use an Handler to post a runnable in the UI Thread queue, or if the context is the Activity ones you can use the runOnUiThread method. The snippet inside the runnable will be run on the UI Thread
put your callback function inside runOnUiThread function :
runOnUiThread(new Runnable() {
#Override
public void run() {
// callback function
}
});
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();
im calling invokeLater direcly from button on actionPerformed with this code:
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
int temp = (jComboBox1.getSelectedIndex() + 1);
heavyProccesingFunction();
}
});
}
and that still freezes the GUI. Why? I get the same result without using the invokelater function.
should I Use
Thread queryThread = new Thread() {
public void run() {
instead?
Edit:
Thanks, new thread should be used.
invokeLater still ends up running the code on the dispatcher thread - just later. The aim of invokeLater is to allow background threads to post work on the event dispatcher thread.
It sounds like you should indeed create another thread - or use a thread pool for the same sort of effect, or SwingWorker for example. Whatever you do, you need to avoid running your slow method on the event dispatcher thread.
I need to implement thread.start() method in my java code. Please let me know through an example of overriding of thread.start() method and how it works?
You should not. Override run instead
You can override start as any other method
Thread myThread = new Thread() {
#Override
public void start() {
// do something in the actual (old) thread
super.start();
}
#Override
public void run() {
// do something in a new thread if 'called' by super.start()
}
};
but you must call super.start() to create a new thread and have run() called in that new thread. The original start does some magic (native code) that you hardly can mimic.
If you call run() directly from within your start() (or any other method), it is executed in the actual thread as a normal method, not in a new thread. There is no reason to use a Thread if you don't want to run some code in a new thread.
You must put your decision logic in the run() method, maybe using some variable set in the constructor (or another method, eventually in start) if that is really needed. I can not find any reason for needing this variable, it should be enough to test the condition in run() as already suggested elsewhere.
class MyThread extends Thread {
private final boolean flag;
public MyThread(boolean someCondition) {
flag = someCondition;
}
// alternative
// #Override
// public synchronized void start() {
// flag = <<someCondition>>
// super.start();
// }
#Override
public void run() {
if (flag) {
// do something like super.run()
} else {
// do something else
}
}
}
but it would be easier to understand and maintain if you do it like #Henning suggested!
It's also a more object oriented solution...
As others said, overriding Thread.start() is not the way to do it. Usually, I wouldn't override Thread.run() either, but use a Runnable.
If you have to decide which method to run after the thread has been spawned, you could do something like this:
final Runnable runnableA = ...;
final Runnable runnableB = ...;
Runnable r = new Runnable() {
#Override
public void run() {
if (...) {
runnableA.run();
} else {
runnableB.run();
}
}
}
Thread thread = new Thread(r);
thread.start();
If, as you say, you have a superclass and a subclass where the run() method is overidden, you can just rely on late binding and the proper method will be invoked automatically:
Runnable couldBeAOrB = ...;
Thread thread = new Thread(couldBeAOrB);
thread.start();
You don't override the start, you override the "run". You can simply implement a thread by:
new Thread() {
public void run() {
//your code here
}
}.start();
//start will call the logic in your run method
Actually, you can call run() to run a thread instead of start() to run a thread. But there is a little difference.
Suppose you create two threads:
Thread t1 = new Thread();
Thread t2 = new Thread();
Case 1 : If you call "t1.run()" and "t2.run()" one after another they will start to run t1 and t2 synchronously (sequentially).
Case 2 : If you call "t1.start()" and "t2.start()" one after another they will call their run() methods and start to run t1 and t2 asynchronously (in parallel).
Agree with Schildmeijer, don't override start, override run() instead.
In fact, although start can be overridden (it's not final), it calls the native start0 method which in turn will cause the VM to call the run method (actually from the context of a native thread/process). The native start0 method has private access, so even if you overrode the start, I can't see how you could reproduce the affect.
The client calling start() is within a thread (lets say, the main thread), it's not until the run method has done its thing that another thread will be spawned.
Take a look at the Sun (ahem, Oracle) tutorial on threads at http://download.oracle.com/javase/tutorial/essential/concurrency/index.html, in particular the section on starting threads.
class Worker implements Runnable{
public void run(){
if("foo"){
runFoo();
} else {
runBar();
} }
private void runFoo(){
// something }
private void runBar(){
// else }
}
I'm pretty sure, you needn't to overwrite the start-Method.
By the way: Take al look at java.util.concurrent.Callable
http://download.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/Callable.html
It is discouraged to override Thread, if possible create an implementation of the Runnable interface instead and run that on a thread. This can also be done with a lambda expression, making everythin super short and simple.
// create a new thread and give it a Runnable with a lambda expression and a custom name
Thread thread = new Thread(() -> {
// put your code here
}, "CustomThreadName");
// start it
thread.start();
If we provide our own implementation of start method then it will work like a normal method call and will work on the current thread stack only. New thread will not be created.
Yes the start() method can be overridden. But it should not be overridden as it is implementation in thread class has the code to create a new executable thread and is specialised.
We can override start/run method of Thread class because it is not final. But it is not recommended to override start() method
class Bishal extends Thread {
public void start()
{
System.out.println("Start Method");
}
public void run()
{
System.out.println("Run Method");
}
} class Main{
public static void main(String[] args)
{
Bishal thread = new Bishal();
thread.start();
System.out.println("Main Method");
}
}
when we are calling start() method by an object of Bishal class, then any thread won’t be created and all the functions are done by main thread only.