I have a MVC-based Java application which I am building, and there is a particular method within my controller (shown below) which behaves as follows:
The model is updated via the initialize method, as I would intend.
The update to the view is not occurring because the model.start() method never terminates (since it is an infinite while loop).
I want to have my view to update first, and then be able to start() my model. How do I alter my code to get the desired behavior?
I suppose one workaround would be replace the model.start() line with code that fires an event which my model is able to observe, but I have not tried that yet, because I want to understand the source of my problem.
Also, I have no idea if this is relevant, but my main application class defines a separate thread for my swing components via SwingUtilities.invokeLater(new Runnable()..., and my view is made up of swing components. There may be some issue related to multiple threads executing, and if so, that would explain why my initializedPerformed() method is not executing in a synchronous way.
Method in the controller which does not behave like I expect/want:
public void initializePerformed(Event e) {
model.initialize(e);
view.getPanel().setName(model.getName());
model.start();
}
model.start():
public void start() {
while (true) {
}
}
If you need model.start() at all, which I highly doubt you do, then start it in a separate thread like this:
new Thread() {
public void run() {
model.start();
}
}
If model is actually inheriting from Thread, then you shouldn't be overriding start() at all. You should override run(), which is called after Thread.start(), and after the new thread has actually been created. If you override start(), no new threads will be created.
From what I remember about swing, all operations must be done by the "main" app thread (I forgot the technical name of it).
The pattern is : create threads to process your data, and leave the main thread only for display. When there is an event that should be displayed, notify the view but let the main thread change it (typically use the semaphore pattern, but if you find it too complex, you can also have an infinite loop that looks what's new each 100 ms for example and calls wait() to check again: business threads will change variables accessible to the main thread.
Best Regards,
Zied Hamdi
http://1vu.fr
Related
I'm writing an android application.
In the main thread, it is possible to define methods and then call the methods, which helps keep the code clean. In a new thread, how does one define methods, to avoid writing all the code in "one block"? Is it possible to call methods defined in the main thread, or can you define them inside the new thread somehow?
So to be clear, what I want to do is this:
volatile Runnable feedToBuffer = new Runnable()
{
#Override
public synchronized void run()
{
if(boolean)
{
MethodA();
}
else
{
MethodB();
}
}
and not this:
volatile Runnable feedToBuffer = new Runnable()
{
#Override
public synchronized void run()
{
if(boolean)
{
//Code that was in MethodA
}
else
{
//Code that was in MethodB
}
}
}
Is that possible?
I realize this info is probably out there somewhere, but haven't found it, so really grateful for any help. :)
It's perfectly possible. Thread is just a sequence of actions, and if it involves a method call, it will be executed within that sequence. It doesn't matter.
Threads are in no way tied to the structure of your code. The main difference between the threads you start and the one you have already when the app starts is the points of entry. When Android starts the main thread, it enters your app in many points, in the activity that would be the lifecycle calls like onCreate() or button click listeners. When you create a new thread, your point of entry is the run method from where you can call anything you want.
There is also a difference in that the main thread runs an event loop. Basically, there is a queue of messages that it has to process. Each time something arrives to the queue, it processes the message, then goes back to waiting. In that sense the main thread never ends. Your thread, however, stops when it reaches the end of the run method. Of course, you can implement a similar event loop for your thread yourself.
Other than that there are no fundamental differences in how the threads operate, you can call methods from any thread freely. Of course, there are rules of multithreading like avoiding blocking the main thread, synchronization, and so on, but it's too much to cover in one answer.
I'm student and I'm working on project with few of my friends. My task is to make something like class library. Classes in this library should provide API for my friend who must make GUI part of application. GUI could be made by any toolkit (Swing, JavaFX, SWT, AWT, all should work, in fact, it should work even if there is no GUI). I need to make class that waits for data to arrive from network. I don't know when data will arrive, and UI must be responsive during waiting, so I put that in different thread. Now problem is how to make GUI respond when data arrive. Well, I tought that this is asynchronous event and GUI should register event handlers, and I should call that methods when event happens. I proposed this solution:
interface DataArrivedListener{
void dataArrived(String data);
}
class Waiter{
private DataArrivedListener dal;
public void setDataArrivedListener(DataArrivedListener dal){
this.dal = dal;
}
void someMethodThatWaitsForData(){
// some code goes here
data = bufRdr.readLine();
//now goes important line:
dal.dataArrived(data);
// other code goes here
}
}
My question is:
Should I replace "important" line with something like this:
java.awt.EventQueue.invokeLater(new Runnable(){
#Override
public void run(){
dal.dataArrived(data);
}
});
Or something like:
javafx.Platform.runLater(new Runnable(){
#Override
public void run(){
dal.dataArrived(data);
}
});
Or maybe I should do something completely different?
Problem is that I'm not sure which of this will work for any type of UI. If it's GUI, dataArrived() could potentialy make changes to GUI and no matter what type of GUI it is, this changes should be drawn on screen properly. I also think that it is better if I do "invoke this code later" so that my someMethodThatWaitsForData() method could trigger event and continue on with it's on work.
I appreciate your help.
Here's an Event Listener article I wrote a while back. The article explains how you write your own event listeners.
You're correct in that you want to write your own event listeners if you want your library to work with any GUI.
I'm most familiar with Swing, so yes, you'll have GUI code that looks like this:
button.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent event){
dal.buttonPressed(data);
}
});
If you want it to be completely agnostic to what GUI is being used the only real solution is to let the receiver handle it in dataArrived. Since every toolkit has its own implementation all you can really do to make it work with any toolkit is to disregard it. Otherwise what you will actually end up with is a list of "supported toolkits" and a case for each one.
If you just want dataArrived to be executed away from someMethodThatWaitsForData then you could make your own dispatch thread or make a new thread each time.
If you want to be truly independent of any front-end system, I would recommend creating two threads. The first is your Waiter, which will just listen for events and put them into a Queue of some sort (see the "All Known Implementing Classes" section). The second will invoke the data listener or listeners whenever the queue is not empty.
The concept of invoking a Runnable in the background is kind of deprecated since the invention of the concurrent package. The main reason that this was done in earlier days, is that the GUI code needs to be executed in a different thread, to guarantee that it stays responsive, even if the main thread is busy doing some calculations, but actual multi-threading was still in its very early days. The resulting invokeLater concept works, but comes with a strong creation overhead. This is especially annoying if you frequently have to do minor things, but each time you need to create an entire new Runnable, just to get that event into the Swing thread.
A more modern approach should use a thread-safe list, like a LinkedBlockingQueue. In this case any thread can just throw the event into the queue, and other listener/GUI-Event-handlers can take them out asynchronously, without the need of synchronization or background Runnables.
Example:
You initialize a new Button that does some heavy calculation once it is pressed.
In the GUI thread the following method is called once the button is clicked:
void onClick() {
executor.submit(this.onClickAction);
}
Where executor is an ExecutorService and the onClickAction a Runnable. As the onClickAction is a Runnable that was submitted once during Button creation, no new memory is accessed here. Let's see what this Runnable actually does:
void run() {
final MyData data = doSomeHeavyCalculation();
dispatcher.dispatch(myListeners, data);
}
The dispatcher is internally using the LinkedBlockingQueue as mentioned above (the Executor uses one internally as well btw), where myListeners is a fixed (concurrent) List of listeners and data the Object to dispatch. On the LinkedBlockingQueue several threads are waiting using the take() method. Now one is woken up as of the new event and does the following:
while (true) {
nextEvent = eventQueue.take();
for (EventTarget target : nextEvent.listeners) {
target.update(nextEvent.data);
}
}
The general idea behind all this, is that for once you utilize all cores for your code, and in addition you keep the amount of objects generated as low as possible (some more optimizations are possible, this is just demo code). Especially you do not need to instantiate new Runnables from scratch for frequent events, which comes with a certain overhead. The drawback is that the code using this kind of GUI model needs to deal with the fact that multi-threading is happening all the time. This is not difficult using the tools Java gives to you, but it is an entire different way of designing your code in the first place.
Is there any difference between creating a thread using the run() method as opposed to using the a constructor?
I noticed that I can start the thread and it acts the same in both ways.
new Thread MyThread().start
For example, as a constructor:
public class MyThread extends Thread{
public MyThread(){
// Do something
}
}
or as the run() method
public class MyThread extends Thread{
public void run(){
// Do something
}
}
Is there any difference between constructor or run()? Thanks!
It does not act the same in both cases
These cases are entirely different.
First, you probably need to learn about Threads and non-blocking processes. A Thread is used to do something asynchronously. So if you wanted to do some background task whilst doing something else then you would use a Thread. A good example is a GUI; you need one Thread to listen for GUI events (mouse clicks, button presses) and another to do any long running processing.
Now, onto your examples.
In Java a Thread consists of a run method that executes asynchronously when the start method is called. So when overriding Thread you change the run method. In reality you should never override Thread, you should use the constructor that takes a Runnable. There are many reasons for this, you should read up on concurrency.
Any code you place in your Thread constructor will be executed in the Thread that calls your constructor so this is not called asynchronously.
If you put the code in the run method, a new thread will be started upon invocation of start, which uses the run method as its starting point. If you put the code in the constructor, however, it will be run in the same thread as that which invoked the constructor, because a constructor is a special case of a method. Thus, if you want to start something in a new thread, put it in run, otherwise, put it in the constructor. Also, if you want to start a thread, never call Thread.run, because of the same reason not to put code in the constructor. Always call Thread.start().
The key difference is this:
The code in your constructor is executed immediately and synchronously when the constructor is invoked.
The program will stop and wait for that code to complete before moving on to the next line of code.
If you put the code inside run() method AND use Thread.start(), the code will be executed in a separate thread (i.e. it will run asynchronously).
Your program will continue to execute (moving to the next line of code immediately) while the code in your run() method runs in parallel.
This is helpful if the code in run() takes a very long time to execute.
That's because your program can continue to do other things while it waits for the thread to finish its work.
There is a difference. The constructor that creates the Runnable or subclass thereof runs in the main thread.
When starting a thread using:
new Thread(myRunnable).start();
you'll actually have run( of myRunnable run in the new thread.
NB You'll want to have a reference to the thread object in many cases. This code example is merely illustrative
On another note, never, ever, ever, give a thread this if starting within a constructor. Your computer could explode, or asphyxiation, drowning, or poisoning may occur.
I'm refactoring some code that runs a multi-stage process. Each step is inside a nested java.awt.EventQueue.invokeLAter.... call. It looks a little like this:
import java.awt.EventQueue;
public class NestedInvokeLater {
/**
* #param args
*/
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
changeTabPanel();
copySomeFiles();
enableNextButton1();
upDateProgressBar(10);
java.awt.EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
readInFiles();
doSomethingToFiles();
upDateProgressBar(15);
java.awt.EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
doSomethingElse();
upDateProgressBar(100);
}
});
}
});
}
});
};
}
I am new enough at Java that I don't get the point of nesting these calls to add 'jobs' to the EDT, and I'm not 100% confident with fiddling with these calls either. I think I understand what the invokeLater call does, and what each step does. Please correct me if this understanding is wrong:
invokeLater is used to add some invocation to the list of jobs to be done in the Event Dispatch thread. Java then deals with when/how each invocation is done, ensuring that the EDT and in turn the GUI doesn't lock as it performs jobs 'in the background'.
Nesting these calls says to me that we should queue a set of jobs, one of which is to queue something, which will queue some jobs....one of which is to queue something. But the first inner invocation is only ever queued once the previous job is done. Everything occurs sequentially (this is in line of my understanding of the whole process), but I don't see why you would use nested requests to queue jobs to do so. I would have, if I was writing this from scratch, have simply created functions for each invocation and called them in turn.
I recognise, being only a novice at Java I am probably missing something huge that makes this nesting important. But there is no documentation of this, and no commenting in the code about the nesting.
What am I missing? What, if anything is the point in this code?
There is no point in doing so many nested invocations. It is based on a good intention, but it's badly implemented.
If you want to do this properly, use a SwingWorker.
The documentation of SwingWorker has a neat example of how you should implement performing several tasks in the background of the application (the PrimeNumbersTask class showed there).
Edit: Here's an example of what you should do with SwingWorker in your case.
class SequentialInvoker extends SwingWorker<Void, Integer> {
#Override
public void doInBackground() {
changeTabPanel();
copySomeFiles();
enableNextButton1();
setProgress(10);
readInFiles();
doSomethingToFiles();
setProgress(15);
doSomethingElse();
setProgress(100);
}
}
To actually show the progress on a progress bar, take a look at the following code, copied from the SwingWorker documentation:
JTextArea textArea = new JTextArea();
JProgressBar progressBar = new JProgressBar(0, 100);
SequentialInvoker task = new SequentialInvoker();
task.addPropertyChangeListener(
new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent evt) {
if ("progress".equals(evt.getPropertyName())) {
progressBar.setValue((Integer)evt.getNewValue());
}
}
});
With this code, your progress bar will show the progress as the SwingWorker works.
One advantage of doing it this way is that other queued up things get to run in between. So, in between the section that does changeTabPanel() and the part that does readInFiles(), the GUI will get to respond to the user clicking on a button etc...
The actual implementation is a bit of a confusing mess and illustrates (IMHO) why anonymous functions were not such a good idea. Your inclination to make the three parts "real" functions and call them sequentially is a good one. But, to maintain the same logic, what you really need to do is make them three runnables and have each invokeLater the subsequent one.
And #Cyrille is correct that doing these major tasks on the EDT is poor practice.
There are three jobs that are used in invokeLater here. Each one does a costly thing, call updateProgressBar and then adds the next job to the EDT.
The thing is, if the code just continued to the next costly thing instead of calling invokeLater to do it, the EDT would not have the chance to repaint the progress bar to show the new value of it. This is probably why the work is broken in three invokelater calls.
Now, this is not what I would call a good code. This is pretty bad practice: one should not do a long process in the EDT because it blocks everything and makes the GUI unresponsive. This should be changed so that the process is done in a separate thread, and then only call invokeLater to update the progress bar.
Edit: To answer more generally the question in the title: there is almost never a sensible reason to nest calls to invokeLater. When you are doing this, you say "queue this job so that it is done in the same thread but later when you feel it would be good". So it gives a chance to the rest of the GUI to repaint itself, like here. But it only makes sense if you have a long running process in the EDT, which you should always avoid.
The code you posted makes absolutely no sense to me - you can just write everything sequentially because you have no parallel threads running which might post events on the EDT. You need the first invokeLater() though, as you use Swing components.
But as your code suggests you are doing some relatively lengthy operations: reading files, do something with them, ... You should run these methods in a new worker thread, NOT the EDT. And, in the run() method of these worker threads, you'll need a call to EventQueue.invokeLater() to have your GUI updated.
I'm developing a small app, which would have Swing GUI. App is doing IO task in another thread, when that thread finishes GUI should be updated acordingly to reflect thread's operation result. Class running in a (worker, non-GUI) has object passed to it in contructor which would be used for updating GUI, so I don't need to put GUI stuff in a non-GUI class, but rather pass object for updating GUI to that class.
As I understand form reading here, (thread/swing) safe options for updating (changing) Swing GUI would be to use javax.swing.SwingUtilities.invokeLater(), javax.swing.SwingUtilities.invokeLaterWait() and/or javax.swing.SwingWorker() which basically are doing the same thing.
This all threading issue with Swing is a little confusing for me, and yet I need to use threads to do anything meaningful in GUI apps and not hung GUI while processing in EDT, so what interests me for now is this:
Are invokeLater and invokeLaterWait like sending message to EDT and waiting for it do it when it finishes processing messages that were before that call?
is it correct from Swing thread safety aspect, to do something like this:
interface IUPDATEGUI {
public void update();
}
// in EDT/where I can access components directly
class UpdateJList implements IUPDATEGUI {
public void update() {
// update JList...
someJList.revalidate();
someJList.repain();
}
}
class FileOperations implements Runnable {
private IUPDATEGUI upObj;
List<File> result = new ArrayList<File>; // upObject is accessing this
public void FileOperations(IUPDATEGUI upObj) {
this.upObj = upObj;
}
private void someIOTask() {
// ...
// IO processing finished, result is in "result"
}
public void run() {
someIOTask();
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
upObj.update(); // access result and update JList
}
}; );
}
}
In case this isn't correct then how should this be done?
If I could, I would prefer to use invokeLater instead of SwingWorker if possible, because I wouldn't need to change my whole class and it's somehow more neat/distinct me (like sending a message in Win32 apps).
Thanks in advance.
Using invokeLater() and invokeAndWait() passes the Runnable parameter into the queue awaiting execution in the EDT. So calling invokeLater() will cause the Runnable to execute in the EDT when the EDT is able to process the request. invokeAndWait() simply waits (in the calling thread) until this execution takes place.
Using SwingWorker is ideal if you want to do background tasks that notify the EDT either at the end of execution or in intermediate states. An example would be to pass the current progress of a process to a JProgressBar.
For your example it seems that SwingWorker is a better choice but if you don't want to change your code too much then calling invokeLater() when the process is done will be just fine.
I'd recommend not using the invokeAndWait until java 7. I found a spurious wake-up on this method that can cause really painful bugs. For me it led to some really rare and hard to debug null pointer exceptions.
http://bugs.sun.com/view_bug.do?bug_id=6852111
It's fixed as of java 7 b77.
invokeLater is fine. This puts the call into the AWT event queue, so that it will get executed in the EDT in due course. Your program will continue running, and does not wait for your callable to get called.