21
Multithreading in JavaFX 10-30-2013

Multithreading in JavaFX 10-30-2013 - Clarkson Universitypeople.clarkson.edu/~jsearlem/cs242/fa13/lectures/27.J… ·  · 2013-10-30Multithreading in JavaFX (javafx.concurrent) Read:

Embed Size (px)

Citation preview

Multithreading in JavaFX

10-30-2013

Multithreading in JavaFX (javafx.concurrent)

Read:

Java Tutorial on concurrency

JavaFX Tutorial on concurrency

Effective Java, Chapter 9

Project#1: due today

return and discuss Exam#1 Exam#2 is scheduled for Tuesday, Nov. 19, 7:00 pm, in Snell 213

Two or more threads sharing an array of account data attempt to read/write the data

Note that: accounts[to] += amount;

is not an atomic operation:

load accounts[to] in some register

add amount to that register

save the register in accounts[to]

Solution: keyword “synchronized” public synchronized void transfer(int from, int to, int amt)

public synchronized void test()

Note: not all methods need to be synchronized (e.g. size() )

One thread examines the state of the system and needs to wait until a certain condition is true

e.g. insufficient funds in an account

wait() method

A different running thread changes the state of the system and needs to wake-up threads that are waiting

e.g. make deposit in an account

notify() and notifyAll()

public synchronized void transfer(int from, int to, int amt) {

try {

while (accounts[from] < amt)

wait();

accounts[from] -= amt;

accounts[to] += amt;

ntransacts++;

if (ntransacts % NTEST == 0) test();

notifyAll();

} catch(InterruptedException e) { … }// handle the exception

}

only one thread can run this code

at a time; all others are delayed

currently running thread goes to sleep

running thread wakes up all waiting threads

running thread exits synchronized method; JVM wakes up

a thread waiting to run this method (if any)

Effective Java, Chapter 9

Item 48: Synchronize access to shared mutable data

Item 49: Avoid Excessive synchronization

Item 50: Never invoke wait outside a loop

Item 51: Don’t depend on the thread scheduler

Item 52: Document thread safety

Item 66: Synchronize access to shared mutable data

“synchronized” code ensures that an object is only observed when it is in a consistent state (mutual exclusion)

“synchronized” code also ensures that when one thread starts running code in a synchronized method, it sees all the modifications to that same object made by other threads

Item 69: Prefer concurrency utilities to wait and notify

// standard idiom for using the wait method

synchronized (obj) {

while (<condition does not hold>)

obj.wait(); // releases lock & re-acquires on wakeup

// continue

}

better to use java.util.concurrent utilities

a specific object is locked (not a class, not a method)

when an object is locked, no other thread may modify it

when a thread successfully calls a synchronized method, it “owns” the lock to the object until either it returns from the method, or it calls wait()

when one thread owns a lock to an object, other threads can call any method which is not synchronized; if, however, another thread calls a synchronized method it is blocked

when one thread calls wait(), it depends on another thread to call notify() or notifyAll()

deadlocks are a serious problem

problem: what if the state values change while the component is in the process of painting itself?

problem: performing a long operation on the event dispatch thread, such as reading or writing a file, will block the whole UI (no other event can be dispatched until this operation completes)

1. Import the pertinent packages

2. Set up a top-level container.

3. Display the container.

4. Be thread-safe.

javax.swing.SwingUtilities.invokeLater( new Runnable() { public void run() { /* code to create and show the GUI */ } // end run } // end Runnable ); // create and run a thread

event handlers can be instances of any class

event handling code executes in a single thread (Event-Dispatching Thread). This ensures that each event handler will finish executing before the next one starts. Painting code also occurs in the event-dispatching thread, so while the actionPerformed() is executing, the GUI is frozen (e.g. can’t be repainted or respond to mouse clicks)

event handlers MUST execute very quickly; if only a few lines of code, can be implemented as an anonymous class

When a swing application is deployed, there are three threads created:

main thread – runs the main program code

toolkit thread – captures user interaction

Event Dispatch Thread – EDT

problem: performing a long operation on the EDT, such as reading or writing a file, will block the whole UI (no other event can be dispatched until this operation completes)

e.g. user enters text

in text field e.g. user clicks

on a button

user presses a key in a text field the event is created and posted on the Event Queue;

at some point, the event is selected from the queue by the EDT and processed by calling the component’s key listener

the component updates its model and posts a paint request on the Event Queue;

at some point, the EDT selects that off the queue and notifies the component to repaint itself

The EDT is responsible for executing any method that modifies a component’s state (including the component’s constructor)

public void actionPerformed(ActionEvent e) {

String text = ReadHugeFile(); // time consuming // bad code alert!

textArea.setText( text ); }

Problem: Potential Deadlock Solution: invokeLater

javax.swing.SwingUtilities:

invokeLater() – posts a new task on the Event Queue

Note: SwingWorker utility class that simplifies the creation of long-running tasks that update the user interface

javax.swing.SwingUtilities.invokeLater( new Runnable() {

public void run() { /* create and show the GUI */ } // end run method

} // end Runnable ); // create and run a thread on the EDT

The system runs two or more of the following threads at any given time.

JavaFX application thread: This is the primary thread used by JavaFX application developers. Any “live” scene, which is a scene that is part of a window, must be accessed from this thread.

Prism render thread: This thread handles the rendering separately from the event dispatcher. It allows frame N to be rendered while frame N +1 is being processed.

Media thread: This thread runs in the background and synchronizes the latest frames through the scene graph by using the JavaFX application thread.