cs4273: distributed system technologies and programming i lecture 4: java threads and multithread...

21
CS4273: Distributed System Technologies and Programming I Lecture 4: Java Threads and Multithread Programming

Upload: quentin-rich

Post on 16-Dec-2015

222 views

Category:

Documents


0 download

TRANSCRIPT

CS4273: Distributed System Technologies and Programming I

Lecture 4: Java Threads and Multithread Programming

2

Multi-threading

Threads

• A thread is a thread of control flow of executing a piece program, similar to a process.

• Multi-threading is a technique of concurrent programming, which runs multiple threads on one piece of program.

• Threads are running in a pseudo-parallel fashion.

• Servers and animation programs often use multiple threads.

PC

PC

PC

Memory

Code Segment

Thread1

Thread2

Thread3

3

States of a Thread Life Cycle

Blocked

NewBorn Dead

Runnable Running

start()

yield()

wait()notify()

sleep()

• run queue: priority queue

head = Thread.currentThread();

• wait queue: activated by notify()

• sleep queue:

Head

Tail

Head Tail

Head Tail

4

Methods in Thread Class

run() method

• run() method is the program body of a thread. A thread executes run method when it starts. You need to override this method to let the thread do your work!

Methods called by threads:

• sleep(ms): make the caller sleep for N milli-seconds.

• yield(): make the caller non-selfish thread. The caller doesn’t mind to give out the CPU to other threads (of the same priority).

• wait() : the caller blocks itself until being waken up.

• notify(): wake up a thread in wait-queue (by moving the thread from wait-queue to run-queue). The caller still holds CPU after the call.

• notifyAll(): wake up all threads in wait-queue.

5

Methods in Thread Class (Cont.)

Methods called by control programs (or threads)

• start(): start the thread. It places the thread to the tail of run-queue.

• setPriority(Thread.MAX_PRIORITY - 2).

• isAlive(): check if a thread is still executing run method.

• currentThread(): return the current running thread.

6

Example of a thread program

public class mythread extends JApplet implements Runnable {……….

public void start() { if (runner == null) { runner = new Thread(this); runner.start(); } } public void stop() {

// N.B. thread.stop method was deprecated! runner = null; } public void run() { Thread thisThread = Thread.currentThread();

// N.B. if “runner’ is null, it won’t do anythingwhile (runner == thisThread) {

thisThread.sleep(t);repaint();………

}

7

Thread Creation

There are two ways to create threads:

1. extend the Thread class to define your thread-class and then construct objects out of your thread-class.

2. use the Runnable interface and implement the run method of the interface.

8

Example of extending Thread class

class BellThread extends Thread{ String Sound; BellThread (String Sound ) { this.Sound = Sound; } public void run(){ while(true){ System.out.println (Sound + " "); try{sleep(20); } catch(Exception e)

{ return; } } } public static void main(String[] args){ new BellThread(“Ding”).start(); new BellThread(“Dong”).start(); } }

process

Ding Thread

Dong Thread

OS

9

Example of Thread Switching

public class threadSwitch extends JApplet { int threadID = 0, star = 0, hash = 0; public void init() { StarThread runner1 = new StarThread();

runner1.start(); HashThread runner2 = new HashThread(); runner2.start(); } public void paint(Graphics g) { super.paint(g); switch(threadID) { case 1: g.drawString("*", star*10, 50); break; case 2: g.drawString("#", hash*10, 100); } }

class StarThread extends Thread {

public void run() {

while (true){

threadID = 1;

if (star >= 50 ) star = 0;

else star++;

repaint(); }

}}

class HashThread extends Thread {

public void run() {

while (true){

threadID = 2;

if (hash >= 50 ) hash = 0;

else hash++;

repaint(); }

}}

10

Runnable Interface

• In addition to extending Thread class, an application often needs to extend from another class, e.g., Applet. But Java doesn’t allow multiple inheritance. Runnable interface is for this purpose.

• Runnable interface has only one method run(). You need to implement the run method.

• Thread class constructor creates threads out of Runnable objects. Thread has two constructors:public Thread (Runnable target); the constructed thread object uses target’s run method! public Thread(Runnable target, String name);the save as above, but the new thread object has a name.

11

Example of Threads using Runnable Interface

class BellRunnable implements Runnable {

BellRunnable(String sound){

this.sound = sound;

}

public void run() {

for(int i=1;i<=100;i++){

System.out.println(sound + " ");

try{Thread.sleep(20); }

catch (Exception e){ return;}

}

}

public static void main(String[] args) {

BellRunnable Ding = new BellRunnable(“Ding”);

Thread DingThread = new Thread(Ding);

DingThread.start();

BellRunnable Dong = new BellRunnable(“Dong”);

new Thread(Dong).start();

}

12

Applets Implement Runnable Interface of Threads

• Runnable interface has only one method run, you can implement the Runnable interface in any class by implementing the run method.

• It is most often used together with Applet class.

class ThreadApplet extends JApplet implements Runnable {private Thread runner;……public void start() {

if (runner == null) {runner = new Thread (this); // run of this classrunner.start (); }

} public void run() {

// thread-code comes here ……

}}

13

Thread Control: stop a thread

Methods “stop”, “suspend” and “resume” for thread control were deprecated due to un-safety.

Stop a thread: add the following codes:1. set the thread pointer runner to “null” when you

want to stop it:……runner1 = null; ……

2. add the following code at the beginning of run() of the thread:public void run() Thread thisThread = Thread.currentThread(); while (runner1 == thisThread) {

code-of-runner; } }

N.B. The following two simple methods don’t work:

a) Only set “runner1 = null” without 2nd part, it cannot stop the execution of runner.

b) Simplify the 2nd part as below, it won’t work either:public void run() { while (runner1!= null) {

code-of-runner;} }

14

Suspend and Resume a thread

• suspend a thread: use a boolean var to indicate suspending the thread and the thread blocks itself by “wait()” in run method.

• resume a thread: use “notify()” to resume the thread.1. use a boolean var.boolean runnerSuspended;public synchronized void actionPerformed

(ActionEvent e) {switch (id) {case SUSPEND: runnerSuspended = true; break;case RESUME:

runnerSuspended = false; notifyAll(); }

2. use the following code in run().public void run() {

while (runnerSuspended) wait();

code-of-runner;}}

15

Example of using wait/notify for suspend/resume

public class threadControl extends JApplet implements Runnable, ActionListener {

public void run() {thisThread = Thread.currentThread();

while (faster == thisThread) { try { synchronized(this) { while (fastSuspended)

wait(); Thread.sleep(20); } catch (InterruptedException e) {} fast++;

repaint(); } while (slower == thisThread) { try { synchronized(this) {

while (slowSuspended) wait();

Thread.sleep(40); } catch (InterruptedException e) {} slow++;

repaint(); }

public synchronized void actionPerformed (Event e) { if (e.getSource() == fsus) fastSuspended = true; else if (e.getSource() == fres) { fastSuspended = false; notifyAll(); } else if (e.getSource() == fstp) faster = null;

………………

16

Concurrent accesses may cause inconsistencyclass unsynchBankTest {

public static void main (String [] args) {Bank b = new Bank ();

for (int i = 1; i <= Ntrans; i++)new Trans (b).start(); }//concurrent threads

}class Bank {

……public void transfer ( int from, int to, int amnt) {

…… accounts[from] -= amnt;accounts[to] += amnt;

} ……} class Transaction extends Thread {

public Trans (Bank b) { bank = b;}public void run () {

while (true) {int from = (Bank.Nacct - 1)*

Math.random();// random numbers for to and amnt;bank.transfer ( from, to, amnt); }

}

load r0, acct[to]add r0, amntstore r0, acct[to]

Bank

Thread1 Thread2 Thread n….

17

synchronized Method for access shared objects

• When multiple threads access shared object concurrently, a monitor is required to guarantee each data access operation is atomic (non-interruptable).

• Java provides a modifier “synchronized” for methods which requires mutual exclusion. When a method is declared as synchronized, the monitor ensures that at any time no more than one thread is active in the monitor (i.e. accesses the object).

• When there is a possibility for two threads to modify a data object in a method, declare the method (or the code-segment) as synchronized, which makes you free of mutual exclusion problem.

18

Example of synchronized Methods

class unsynchBankTest {public static void main (String [] args) {

Bank b = new Bank ();for (int i = 1; i <= Ntrans; i++)

new Trans (b).start();}

}class Bank {

public synchronized void transfer ( int from, to, amnt) {……accounts[from] -= amnt; // it’s safe now!accounts[to] += amnt;

} ……}class Trans extends Thread {

public void run () {while (true) {

int from = (Bank.Nacct - 1)* Math.random();// random numbers for to and amnt;bank.transfer ( from, to, amnt);

}}}

19

Thread Coordination

• Threads often need to coordinate with each other to get a job done, such as the Producer-Consumer problem.

• The coordination among threads can be achieved by wait and notify methods. When a thread cannot proceed further and waits for the change of a state, it calls wait() to block itself; when a thread changes a state which may unblock others, it calls notify().

• In Java, there is only one wait-queue, a FIFO queue, for each application. If more than one thread waiting, notify wakes up the head of wait-queue. Threads cannot wait() on specific events. Therefore, notifyAll() is often used to make sure the right thread is waken up.

Box

Boy Monkey

Put Get

20

Example of Threads Coordination

class Box {

boolean banana = false; //no banana

synchronized void get() {

while (!banana) // ? not use if

wait(); // wait for banana

System.out.println("take banana away”);

banana = false; // no more banana

notifyAll(); //notify box is empty

}

synchronized void put() {

while (banana)

wait(); // wait for box empty

System.out.println(“put banana in”);

banana = true;

notifyAll(); // notify banana is ready

}

Box

Boy Monkey

Put Get

21

Example of Threads Coordination (Cont.)

class Monkey extends Thread { Monkey(Box box) { this.box = box; } public void run() {

while(true) { box.get();

} }class Boy extends Thread { Boy (Box box) { this.box = box; } public void run() { while(true){

box.put(); }

}

class MonkeyEatBanana { public static void main(String args[]) { Box box = new Box(); new Monkey (box).start(); new Boy (box).start(); } }

Summary of producer-consumer problem:

• define a class for the share objects, with methods (synchronized if necessary) for accessing the objects.

• define classes for producer threads and consumer threads, using the methods on the shared objects to access them.

• define a main routine which instantiates shared objects and threads, and starts the threads.