Upload
others
View
3
Download
0
Embed Size (px)
Citation preview
Multithreading
10-25-2013
Multithreading:
java.lang.Thread class
java.lang.Runnable interface
Synchronization Coming next: Multithreading in JavaFX (javafx.concurrent)
Read:
Java Tutorial on concurrency
JavaFX Tutorial on concurrency
Effective Java, Chapter 9
Project#1: due Wed, October 30th
Exam#2 is scheduled for Tues., Nov. 19, 7:00 pm, Snell 213
Consider a GUI with two buttons: when you click on “start”, it activates a ball that will be repeatedly drawn in the GUI (simulating a bouncing ball or atom), and when you click on “close” the application terminates.
public void bounce() { draw(); for (int i = 1; i <= 10000; i++) { move(); try { Thread.sleep(5); } catch(InterruptedException e) {} } }
Problem with single threaded version: non-responsive GUI!! Why? Because the one thread of control is executing the for loop, so can’t check the button click until the loop terminates.
What is a thread?
What resources do threads share? What is not shared?
Methods for creating a thread:
Implement the Runnable Interface (preferred)
Extend the Thread class
What are thread states?
new, runnable (running), blocked (waiting for a lock), waiting (for another thread), timed_waiting, terminated
Java threads are managed by the Java Virtual Machine (JVM)
Typically implemented using the thread model provided by underlying OS
The java.lang package contains the following:
Thread class
Runnable interface
When a Java Virtual Machine starts up, there is usually a single non-daemon thread (which typically calls the method named main of some designated class).
A thread is a thread of execution in a program.
The Java Virtual Machine allows an application to have multiple threads of execution running concurrently.
thread ≈ “lightweight” process
the threads share the resources & data in the program
each thread has its own stack and program counter
public class Thread extends Object implements Runnable
Thread() constructor; Creates a thread, but must “start” the thread to
activate its run method
void run() override this method; customize the code to be
executed in a separate thread
void start() “starts” the new thread; this method returns
immediately; the new thread runs concurrently with others
static void sleep(long ms) puts the currently executing thread to sleep for the
given time
Contains one method: void run()
When an object implementing interface Runnable is used to create a thread, starting the thread causes the object's run method to be called in that separately executing thread. The general contract of the method run is that it may take any action whatsoever.
This interface is designed to provide a common protocol for objects that wish to execute code while they are active.
A class that implements Runnable can run without subclassing Thread by instantiating aThread instance and passing itself in as the target. In most cases, the Runnable interface should be used if you are only planning to override the run() method and no other Thread methods.
1.Extend Thread.
override the run() method
OK for standalong apps that don’t extend another class, but is not the preferred method
2.Implement the Runnable interface.
Good for most cases.
Implement the run() method
Variation: Construct a Thread, passing an inner class that is Runnable.
o OK for small run methods with little outside interaction.
better
Contains one method: public void run()
When an object implementing interface Runnable is used to create a thread, starting the thread causes the object's run method to be called in that separately executing thread. The general contract of the method run is that it may take any action whatsoever.
NEVER CALL RUN DIRECTLY, instead call start() which creates the thread, sets up the context, and calls run()
public class Ball extends Thread { // constructor; draw(); move(); etc. public void run() { // code to animate the ball } addButton(p, "Start", new ActionListener() { public void actionPerformed(ActionEvent evt) { Ball b = new Ball(canvas); b.start(); } });
public class Ball extends Thread { // constructor; draw(); move(); etc. public void run() { // code to animate the ball } addButton(p, "Start", new ActionListener() { public void actionPerformed(ActionEvent evt) { Ball b = new Ball(canvas); b.start(); } });
Not a good use of inheritance: a ball “is a” thread???
// multithreaded version, continued addButton(p, "Start", new ActionListener() { public void actionPerformed(ActionEvent evt) { Ball b = new Ball(canvas); b.start(); } });
Note:
Ball b = new Ball(…); // doesn’t run the thread
To launch a runnable thread, call start()
NEVER call run() directly
start() creates the thread, sets up the context, & calls run()
public class Ball implements Runnable { private JPanel box; private Thread t; // this is composition, not inheritance public Ball(JPanel b) { box = b; t = new Thread(this); t.start(); } public void run() { // code to animate the ball }
public class Ball { // not Runnable private JPanel box; private Thread t; // added, just like version 2 public Ball(JPanel b) { box = b; t = new Thread(new Runnable() { public void run() { /* run method here same as version 2 */ }}); t.start(); // just like version 2 }
public static void main(String[] args) {
for (int i = 0; i < 1000; i++)
System.out.println("A");
for (int j = 0; j < 1000; j++)
System.out.println("B");
}
Prints 1000 As followed by 1000 Bs
public class AsBs2threads {
public static void main(String[] args) {
Thread tA;
tA = new Thread(new Runnable(){ // create ThreadA
@Override public void run(){ for (int i = 0; i < 1000; i++){ System.out.println("A"); try { Thread.sleep(10); } catch(InterruptedException e) {}} }});
// continued on next slide
// main, continued Thread tB; tB = new Thread(new Runnable(){// create ThreadB @Override public void run(){ for (int i = 0; i < 1000; i++){ System.out.println("B"); try { Thread.sleep(10); } catch(InterruptedException e) {}} }}); tB.start(); // start ThreadB tA.start(); // start ThreadA } }
1.new 2.runnable
3.blocked 4.dead
e.g. Ball b = new Ball(…); b is in the “new” state
(not yet runnable)
b.start(); // puts b in the “runnable” state (not necessarily running yet)
Ball b = new Ball(…); // b is in the “new” state // (not yet runnable)
b.start(); // puts b in the “runnable” state // (not necessarily running yet)
Every thread has a priority.
Threads with higher priority are executed in preference to threads with lower priority. Each thread may or may not also be marked as a daemon.
When code running in some thread creates a new Thread object, the new thread has its priority initially set equal to the priority of the creating thread, and is a daemon thread if and only if the creating thread is a daemon.
the “child” thread inherits the priority of the parent
can modify a thread’s priority w/ method setPriority()
MIN_PRIORITY <= priority <= MAX_PRIORITY
1 10
NORM_PRIORITY == 5
from the pool of runnable threads, choose the one with the highest priority
if a tie, use round-robin
preemptive – if a thread enters the runnable state and it has a higher priority than the currently running thread, it becomes the running thread
Generally, the highest-priority thread runs until either:
it calls the yield() method
it is no longer runnable
- it becomes blocked
- its run method terminates or it dies
a higher-priority thread has become runnable
its time slice expires
Since threads share data, what happens if two different threads attempt to update the same variable at the same time?
Problem!!! Solution? Synchronization