multithreading 10-25-2013jsearlem/cs242/fa13/lectures/25... · 25/10/2013  · java.lang.thread...

Post on 01-Aug-2020

3 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

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

top related