How can I access a synchronized buffer from a Swing Gui? - java

I have to write a GUI application that uses RMI to keep consistent state across multiple clients.
Because the RMI calls will block, I put them in a separate thread from the GUI thread.
To push information to and from the GUI thread my first thought was to use a synchronized buffer.
But if I call a synchronized method on the Buffer, the GUI will freeze. If I don't use the synchronized keyword the Buffer won't be thread safe.
From the Java Docs:
It is not possible for two invocations of synchronized methods on the same object to interleave. When one thread is executing a synchronized method for an object, all other threads that invoke synchronized methods for the same object block (suspend execution) until the first thread is done with the object.
Is there some other alternative that will make the buffer thread safe and not freeze the GUI.

One approach is to separate the model data from the view using the Model–View–Controller pattern, shown here, here and here. In the last example, the model evolves on a background thread and the view is periodically updated using a javax.swing.Timer. SwingWorker, illustrated here, is an alternative.

See if any of the objects in java.util.concurrent would do the trick. They offer more fine-grained control than synchronized.
For example, here's what you could do with a Semaphore:
In some shared class
public class Shared {
public final Semaphore mutex = new Semaphore(1);
}
In the RMI thread
// synchronizing with other clients...
// now we're at the critical section. Block until we have the lock
Shared.mutex.acquireUninterruptibly();
// update state
Shared.mutex.release();
// critical section over. Schedule an update on the GUI thread.
In the GUI thread
// if the critical section is free, check for updated state. Else, just wait
if (Shared.mutex.tryAcquire()) {
try {
// read state and update GUI
} finally {
Shared.mutex.release();
}
}
Here, the GUI thread is not guaranteed to see every single update, but if the RMI thread isn't constantly updating state it should work.

You have a number of approaches you could try.
You could fire an event from the RMI/read thread that can be used to notify the UI of changes. Just make sure that you only update the UI in the EDT.
You could use a SwingWorker to process the RMI requests in the background and the publish`process` methods to sync the results back to the client.

Related

Java UI Rendering Model using Threads. Volatile vs Synchronized Block for the InputState

The issue.
The UI Thread processes Key/Pointer events and write them in a class named InputState.
The Rendering thread reads from the InputState and updates its state continuously.
I see 3 solutions
use synchronized keyword on all get/set methods in the InputState. But that means every single time Render threads check for events possibilities (about 50 times per loop), it must acquire a lock. Not very efficient but allows for fine multi threading between UIThread and Render thread.
Synchronize on the InputState single reference. Render thread synchronizes on the whole object and does its 50 gets checks sequentially while holding the lock and then releases the lock.
Have 2 instances of the InputState. Let's say 1 and 2. Rendering thread access the "live" (InputState1) with the volatile keyword. None of the InputState method are synchronized.
When a new event is processed by the UI thread, the UI thread updates the shadow copy of the InputState, InputState2, then once finished, updates the live volalite reference. That crucial operation is atomic right? Now Render thread sees InputState2 as "live". InputState1 is now the shadow InputState. BUT!
UI Thread must make sure of something. UIThread must now wait that the rendering thread exits any methods before using it again. Because the Render thread might be sooo slow that it gets stuck in a get method in InputState1 while 2 events are processed in a Row by UIThread. might it not? I am not yet sure how to fix this. Hence my question here. I could use a 3rd InputState instead of 2 and rotate them while checking the volatile loop count of the rendering thread.
Which is the best option in your opinion?

Java Thread Synchronized object for wait and notify

When we are using wait and notify in thread environment. I have a class to process data as background process. And when there is no data to process it should call wait.
synchronized(some_object){
wait();
}
In another class I am adding the data again. I need call notify() method.
synchronized(some_object){
runnabale_object.notify();
}
Why i should use same object for synchronized block in those two different class. As i read synchronize is used to
The "Synchronized" keywords prevents concurrent access to a block of
code or object by multiple Threads.
But these two are different block. But i can understand the problem when we use multiple threads. While one thread block other can call notify before the same thread call notify.
My Questions
Can we use different lock objects (synchronized(object)) for single threaded environment?
Best way of use same lock object when we have wait and notify in different classes?
Can we use different lock objects (synchronized(object)) for single threaded environment?
In a single threaded environment, you don't need the locks. You can use anything you want or nothing at all.
In a single threaded environment you can guarantee no thread is wait()ing so the notify() will not do anything.
Best way of use same lock object when we have wait and notify in different classes?
When you notify(), you must perform a state change. When you wait() in a loop you much check for that state change. If you don't do this you can have two problem.
the notify() is lost
the wait() wakes spuriously, ie no notify.
when there is no data to process it should call wait.
Not when, but while.
Wait and notify are low-level primitive operations that are meant to be used in a very specific way.
In a consumer thread:
synchronized(lock) {
while (thereIsNothingToProcess()) {
lock.wait();
}
processSomething();
}
In a producer thread:
synchronized(lock) {
makeSomethingAvailableToProcess();
lock.notifyAll(); //or lock.notify() if you think you can get away with it.
}
If you follow this exact pattern, then:
You will not run into trouble when multiple consumers are competing for the same thing-to-be-processed,
You will not run into trouble because of spurious wakeups, and
You will not run into trouble because of the lost notification problem.
I've had the same question so I looked it up. The reason that two synchronized block can be used in the same object, is that 'wait()' will actually release the monitor so that other thread can obtain the guardian of the same object.

How does a Java thread synchronize with invokeLater()?

I have a non-GUI thread that starts a JFrame using
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
cardReadPunchGUI = new IBM1622GUI(); // instantiate
cardReadPunchGUI.setVisible(true);
}
});
Part of IBM1622GUI's constructor instantiates a "model" for itself, which my non-GUI thread needs access to:
cardReadPunch = IBM1622GUI.getModel();
What is the correct way for my non-GUI thread to synchronize with the new GUI that's been "invoked later"? (Without synchronization, of course, IBM1622GUI.getModel() just tends to return null.)
Use
javax.swing.SwingUtilities.invokeAndWait(Runnable doRun);
instead.
Causes doRun.run() to be executed synchronously on the AWT event
dispatching thread. This call blocks until all pending AWT events have
been processed and (then) doRun.run() returns.
Id suggest you share an CountDownLatch initialized to 1 with both both the non-GUI and GUI threads.
The non GUI thread when it starts will call latch.await() which will put it in a blocked state.
The GUI thread will call latch.countDown() when it finishes its initialization after which the non-GUI thread will exit from the await call and both threads are synchronized.
Well, if you have access to it you could always move that particular logic outside of the Swing thread and onto the thread that calls invokeLater. There's nothing unsafe about doing what you're doing there off of the Swing thread, assuming the constructor for IBM622GUI is well behaved.
Other than that, you could make use of various other mechanisms.
You could use invokeAndWait, as cgull beat me to saying.
You could have the runnable set the value of a Future instead of a direct reference, and block on the main thread by calling the future's get method.
You could have a CountDownLatch with a starting count of 1 which you await() on your main thread, and countDown() from the Swing thread.
There are many, many utilities to help with synchronization.
Typically you pass parameters to the Thread. Run the logic in the background. And then post back any modifications you need to do to any of those objects, or UI elements on the UI thread using SwingUtilities.invokeLater(). Typically I create a simple a utility that allows me to specify what should run on the background thread, and what should run on the UI thread. SwingWorker is something you could use although I find it extremely painful to use. Something simple like this:
new AsyncThread<Param,T>() {
public T executeInBackground( Param param ) {
// do something long running
T result = // do something long running;
return T;
}
public void executeOnUI( T result ) {
// update the UI here, or modify the model, etc.
}
}.execute( param );
AsyncThread would execute the executeInBackground() method on another thread. Then internally it would post back to UI thread using SwingUtilities.invokeLater(). Then executeOnUI would run on the UI thread. The execute() method could create a thread to run in background, handle exceptions, etc.
I'd let the GUI possibly kick off the thread, and let the GUI pass it's model, or whatever part it needs, to the thread. Instead of the other way around. That way you can have the UI give feedback about that background thread that's running. But, you can't let the background thread touch (write/modify/change) members of that model that the UI thread would be reading/writing too at the same time. So if you plan on modifying the model in response to the background thread, post it back to the UI thread to be safe.

Explain what the following code does?

java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new NewJFrame().setVisible(true);
}
});
Please tell me what does the above code does actually. I am looking for line by line explanation. especially the first line and tell me why do we use that and in what scenarios we have to use this.
In this Example you see an anyonmous class that derives from Runnable. This anonymous class overrides the run method of the interface runnable. Then this anonymous class is instantiated and passed to the EventQueue.invokeLater method, which is a static method. This method appends the object into... well... the eventQueue. In the EvenQueue are many events, like keyboard events or mouse events or whatever. There is a Thread that continuesly polls data from this queue. Once that Thread reaches the anonymous class that was instantiated here, it will execute the run() method, which will instantiate an Object of class NewJFrame and set it to be visible.
The whole point of doing this this complicated is that the new JFrame().setVisible(true) part is not executed in the main thread, but in the event dispatching thread. In Swing you must execute all code that modifies the user interface in the event dispatching thread.
Single-Thread-Model and EDT
Most modern UI libraries adopt the single-thread-model. That means, all the manipulation upon UI components MUST be done on the same single thread. Why? That's because allowing UI components being updated from multiple threads will lead to chaos since most Swing object methods are not "thread safe". For simplicity, efficiency and robustness, single-thread-model is adopted.
In Swing, the very thread that serve the single-thread-model is called the Event Dispatching Thread, i.e. EDT. It is not provided by Swing. It is provided by Abstract Window Toolkit, i.e. AWT.
Worker thread vs UI thread
A non-trivial GUI application usually has many threads. In modern GUI application, there can be many worker threads to do dirty work, but there's only one UI thread (Swing calls it EDT) to update the GUI. Worker threads usually need to reflect their work progress in GUI, so they need to communicate with the UI thread about that. So how does this communication happen?
java.awt.EventQueue
The communication happens through a message queue model. The java.awt.EventQueue is the very class that provides a event queue globally. This global event queue serves as the communication channel to the EDT. EDT picks up messages from this EventQueue and update UI components accordingly. If some other part of your program wants to manipulate the UI, that part of code should call EventQueue.invokeLater() or EventQueue.invokeAndWait() to queue a message into EventQueue. EDT will process all the pending messages in the EventQueue and eventually get to the message.
the main thread
Your code snippet usually resides in the main() thread, the main thread can be viewed as some kind of a worker thread here. Only that instead of updating the GUI by posting messages to EventQueue, it initiates the GUI. Anyway, initiation can be viewed as a kind of work, too.
After the GUI is initiated, the main thread will exits and the EDT will prevent the process from exiting.
And another good explanation:
Java Event-Dispatching Thread explanation
An interesting article:
Multi-threaded toolkit, a failed dream?
This is a block of code that is instructed to execute at a later time (sometimes called a deferred). The inner class (new Runnable() {...}) is essentially allowing you to pass a block of code that will be run. The invokeLater method guarantees that the block of code will be run, but makes no guarantees of when. Sometimes it's not safe to have certain code run immediately, and its too verbose to do the multi-threading yourself. So Java provides this utility method to safely run the code. The code will be run very soon, but not until it's safe to do so.
The invokeLater call will put the specified runnable on a queue to be processed later. That is, the code inside the run() method will not have been run yet when the invokeLater method call returns.
There are two typical use-cases for this type of code.
The currently executing code is run in a background thread. Background threads cannot access most of the swing API. Read more here for the reason for this. If the current thread is already the UI thread there is no reason and the call can safely be removed.
The current block must be exited, ie the code reach the last brace. This may cause resources to be released and so on. This is not so common.
An anonymous class is passed as parameter to the invokeLater call. It is the same as this code.
private void foo()
{
java.awt.EventQueue.invokeLater(new JFrameCreator());
}
private class JFrameCreator implements Runnable
{
public void run() {
new NewJFrame().setVisible(true);
}
}
Source
The invokeLater() method takes a Runnable object as its parameter. It sends that object to the event-dispatching thread, which executes the run() method. This is why it's always safe for the run() method to execute Swing code.
-IvarD

Pass off execution to different/specific thread in Java

I have about 4 threads. One thread keeps checking some data that the other thread is updating. The others are doing some processing in the background. All have been started at this point.
My question is when the checking thread sees that the data has not been updated yet I currently sleep for a little bit but is there any way for me to tell the system to back to executing the thread that does the updating?
That or is there any way I can put something like a listener on the data(a String) and once its updated an event will fire that will do what it needs to do?
I tried using yield() and it seemed to just keep returning to the thread I called yield() from.
Thanks
This kind of simple notification is what Object.wait() and Object.notify() are intended for.
In your updater thread, you have
void updateData() {
synchronized (theData) {
theData.doSomeUpdate();
theData.notifyAll(); // tell other threads of a change
}
}
And then in your checking thread, have
void waitForUpdates() {
synchronized (theData) {
while (notCancelled) {
theData.wait(); // wait for notification
handleUpdate(theData);
}
}
}
Don't use Thread.sleep() since you can't really wake up the thread, unless you interrupt it, and that's a little nasty. Instead, use the wait/notify process above.
You can also look at passing notifications via an explicit BlockingQueue that is shared between the threads. The updater thread puts events in the queue, and the checker thread uses take() to fetch update events from the queue, waiting if there are no updates in the queue.
The difference with this scheme is that the updater thread can pass specific information about what has changed, rather than just saying "something changed", as is the case with wait/notify.
Also, the thread is notified of each update explicitly, so no updates are missed. It's also more flexible than wait/notify, since notification of updates does not require a lock on the data.
You cannot force a given thread to run. You can, however, put your checking thread to sleep and have your producing thread notify it when data is ready.
This is a classic "producer/consumer" problem, and java.lang.Object has methods to help you implement this (wait/notify/notifyAll). For higher level constructs, check out java.util.concurrent
You should consider wait() and notify().

Categories

Resources