View
219
Download
0
Tags:
Embed Size (px)
Citation preview
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