1 cs2200 software development lecture: multi-threading ii a. o’riordan, 2009

21
1 CS2200 Software Development Lecture: Multi-threading II A. O’Riordan, 2009

Post on 20-Dec-2015

219 views

Category:

Documents


0 download

TRANSCRIPT

1

CS2200 Software Development

Lecture: Multi-threading II

A. O’Riordan, 2009

2

Thread Priorities

• Java Threads have a priority – can use getPriority() method in Thread class

• Priority is thread ranking - Some threads can either run for a longer time-slice or run more often (depending on the operating system)

• Peers (or equals) get the same time/number of runs

• Priority is set from constants MIN_PRIORITY (currently 1) to MAX_PRIORITY (currently 10) using the setPriority(int) method

• NORM_PRIORITY is the midrange value (currently 5).

3

Thread Priority Issues

• Higher priority threads can interrupt (pre-empt) lower priority ones

• To lower the priority of a thread by 1t1.setPriority(t1.getPriority() -1);

• Each new thread has the same priority as that of the thread that created it

• Low priority threads are in danger of starvation– when one thread cannot access the CPU because one or more

other threads are monopolizing it– yield() method relinquishes control which may enable others to

be run

4

ThreadGroup

• Every Java thread is a member of a thread group, by default the same group as that of the thread issuing the constructor for it– Class ThreadGroup (package java.lang)– Add thread to group, grp, using a constructor

Thread(grp, new T(), "t1");

• Throws SecurityException if the current thread cannot create a thread in the specified thread group

• Purpose of thread groups is to enforce security, e.g. it is not legal to stop a thread that is not in your group

• Members of a thread group can invoke operations that affect all members

5

Example Part I

public class ThreadGroupTest {

public static void main(String[] args){

ThreadGroup grp = new ThreadGroup(“Groupies");

Thread t1 = new Thread(grp, new Task(), "t1");

Thread t2 = new Thread(grp, new Task(), "t2");

t1.start();

t2.start();

System.out.println("ThreadGroup name:” + grp.getName());

System.out.println("There are currently " + grp.activeCount() + " threads running");

System.out.println("The maximum priority of a Thread that can be contained within " + grp.getName() + " is " + grp.getMaxPriority());

}

}

6

Example Part II

class Task implements Runnable{ public void run(){ for (int i = 1; i < 5; i++) { System.out.println("Thread " +

Thread.currentThread().getName() +" has a priority of " +

Thread.currentThread().getPriority()); } } }

7

Executors (Java 5)

• To abstract thread management from the rest of your application, pass the application's tasks to an executor

• Executors define a high-level API for launching and managing threads. Executor implementations provided by java.util.concurrent provide thread pool management suitable for large-scale applications– ExecutorService interface that supports launching new tasks– If r is a Runnable object, and e is an ExecutorService object you can

replace Thread t = new Thread(r); t.start() with e.execute(r)

• However, the definition of execute is less specific. The first option creates a new thread and launches it immediately. Depending on the implementation, execute may do the same thing, but is more likely to use an existing worker thread to run r, or to place r in a queue to wait for a worker thread to become available

8

Thread Pools

• A Thread pool consist of worker threads that exists separately from the Runnable they execute

• A fixed thread pool always has a specified number of threads running; if a thread is somehow terminated while it is still in use, it is automatically replaced with a new thread

• Tasks are submitted to the pool via an internal queue, which holds extra tasks whenever there are more active tasks than threads

• Executors method newFixedThreadPool() returns an ExecutorService that creates 2 threads (method newCachedThreadPool returns an ExecutorService that creates threads as they are needed)

9

Executors Example

Assuming there’s a class Task that implements Runnable:

Task task1 = new Task("task1");

Task task2 = new Task("task2")

Task task3 = new Task("task3");

System.out.println("Starting threads");

ExecutorService threadExecutor = Executors.newFixedThreadPool(2);

threadExecutor.execute(task1);

threadExecutor.execute(task2);

threadExecutor.execute(task3);

threadExecutor.shutdown(); // shutdown worker threads

10

What’s happing

• The code in method main executes in the main thread• Creates three Task objects (no extra threads are this stage)• Create an executor that uses a fixed thread pool by invoking

newFixedThreadPool() factory method in Executors (returns a ExecutorService object)

• execute() creates a new Thread inside the ExecutorService and returns immediately from each invocation

• ExecutorService method shutdown() will end each Thread in threadExecutor as soon as each finishes executing its Runnable and there are none queuing

• The program will not terminate until its last thread completes execution

11

Daemon threads

• A Java program exits when all of its threads have completed

• but this is not the full story. What about the hidden system threads, such as the garbage collection thread and others created by the JVM? We have no way of stopping these.

• These system threads are called daemon threads. A Java program actually exits when all its non-daemon threads have completed

• Programmer can create daemon threads as well (not covered).

12

Process v Thread

• Process - active program – maintains its own set of resources; Thread – sometimes called lightweight process – uses resources of enclosing process

• Process can be considered as data (address space, files, etc) plus one or more threads

• All threads live in the same memory space

• Threads can easily exchange data among themselves simply by accessing shared variables (static or instance fields), but threads must also ensure that they access shared variables in a controlled manner

13

Technical Issues

• Deciding what should be a thread – not all objects should have their own threads

• Liveness – a thread can be starved of CPU cycles or threads can be deadlocked (waiting for each other in order to continue)

• Synchronization – need exclusion mechanisms to maintain threads in a consistent state

• Non-determinism – different executions of a program can result in different interleaving

• Thread construction overhead – performance hit of creating and setting threads running

14

Execution context

Execution context managed by JVM

• Execution context – a way to create/delete execution context, save and maintain state, dispatch to another thread’s execution context

• Scheduling – determine which thread to switch to and when (e.g. run-until-blocked, round robin time-slicing)

• Synchronization – coordinate the use of shared resources, e.g. mutexs (mutual exclusions) for shared resources; buffering for producers and consumers

Op Sys (e.g. Linux) has it’s own execution context underneath

15

Producer/Consumer: The Box class

public class Box { private int total;

public Box() { total = 0; }

public void put() { int bigger = total + 1; System.out.println("Putting something in" + "; new total is " + bigger); total = bigger; }

public void get() { int smaller = total - 1; System.out.println("Taking something out" + "; new total is " + smaller); total = smaller; }}

16

Thread accessing another object

public class Producer extends Thread {

public Box box;

public Producer(Box b) { box = b; }

public void run() {

try {

for (int i = 0; i < 50; i++) {

box.put();

sleep(100);

}

}

catch (InterruptedException e) { }

}

}

... And assume asimilar threadfor consuming the items and amain programstarting bothThreads…

... And assume asimilar threadfor consuming the items and amain programstarting bothThreads…

17

Race Condition

• But the final total is not necessarily 0!– the two threads are sharing resource, and because of thread

scheduling, there is no guarantee that the other thread does not jump in and change it in the middle of an update

• race condition - the threads are racing to complete their tasks and the final result depends on which one wins the race– a thread must "lock" the data or objects it is going to change– if an object is locked, no other object can modify its state– Java allows us to do this by specifying that a method is

synchronized– if the thread running it sleeps, the data remains locked– Java handles all the locking and unlocking for us

18

Synchronizing

• Add keyword synchronized to code:

public synchronized void get() {…}public synchronized void put() {…}

• Aso try to ensure co-ordinated behaviour by only put an item when box is empty and only get an item when there is item in box

public synchronized void put(Thread th) { while (total > 0 ) try { th.sleep(10); } catch (InterruptedException ie) { }// rest of code} ... doesn't work again!... doesn't work again!

this work!this work!

19

Deadlock

• the put() method is synchronized so once it starts, the box object is locked, and no other thread can get access

• so if put() is invoked while total == 1, it locks the object, puts the thread to sleep, wakes up 10 millisecs later, sees that total is 1, goes back to sleep, and repeats for ever

• We have Deadlock!

20

Avoiding deadlock

– instead of putting the thread to sleep, we can tell the method to wait until an appropriate time– each time the consumer or producer changes the total, it should notify all other threads that

the value has changed– the threads then reactivate, and check the condition

public synchronized void put() { while (total > 0 ) try { wait(); } catch (InterruptedException ie) { } int newTotal = total + 1; notifyAll(); ...}

wait() and notifyAll()are methods of the Object class

wait() and notifyAll()are methods of the Object class

21

Resources

• Java Threads/Concurrency Tutorials – http://java.sun.com/docs/books/tutorial/essential/concurrency/

– http://www.freejavaguide.com/java-threads-tutorial.pdf

– http://java.sun.com/j2se/1.5.0/docs/guide/concurrency/overview.html

• Dedicated Books on Java Concurrency – Java Concurrency in Practice, Brian Goetz et al., Addison-Wesley

Professional, , 2006

– Concurrent Programming in Java, Second Edition, Doug Lea, Addison-Wesley, 1999 (Java 2)

– Java Threads, Third Edition, Scott Oaks and Henry Wong, O'Reilly, 2004