Download presentation
Presentation is loading. Please wait.
1
26-Jun-15 Threads and Turns
2
Thread review There are two ways to create a Thread object.. Extend Thread and supply a run method: class MyThread extends Thread { public void run( ) {... } } Thread someThread = new MyThread(); Implement Runnable : class Something implements Runnable { public void run( ) {... } } Something something = new Something(); Thread someThread = new Thread(something);...And just one way to start a Thread running someThread.start();
3
Random facts about Threads Threads are Objects, with all that that implies Threads can be saved in variables, they have a toString() method, etc. Every Thread has a name You can specify the name when you construct the Thread, or just let Java generate a name for the Thread You can get and set the Thread’s name Every Thread has a priority Higher priority Threads run in preference to lower priority Threads You can get and set a Thread’s priority, but it’s seldom a good idea Every Thread is either a daemon Thread or a non-daemon Thread Java exits when all non-daemon Threads have quit running Daemon Threads will die when Java exits You can get and set the Thread’s daemon status
4
Monitors Threads are synchronized by means of monitors Any Object can be a monitor A Thread that “holds” (or “has a lock on”) a monitor prevents any other Thread from using that monitor A synchronized statement uses an explicit object as a monitor synchronized( SomeObject ) {... } A synchronized instance method uses the instance ( this ) as a monitor public synchronized void someMethod () {... } A synchronized static method uses the class’s Class object as a monitor public static synchronized void someMethod () {... } If this is in class Thing, the Class object is given by Thing.class
5
Threads with monitors The following methods (defined in the Object class) can only be executed when the current Thread holds a monitor monitor.notify() Wakes some arbitrary Thread that is waiting on this monitor The wakened Thread will be able to proceed after this current Thread relinquishes the lock, and the wakened Thread gets it monitor.notifyAll() Wakes all Threads that are waiting on this monitor After the current Thread relinquishes the lock, some one wakened Thread will get it and be able to proceed monitor.wait() and monitor.wait(long timeoutInMilliseconds ) This Thread relinquishes the lock, and becomes dormant until something wakes it Things that can wake a dormant Thread are: Some other Thread invokes notify() or notifyAll() Some other Thread calls this Thread’s interrupt() method The timeout period has passed Some other random thing happens (no, seriously!) Trying to execute one of the above methods when the current Thread does not hold a monitor results in an IllegalMonitorStateException
6
How to wait When a Thread wait s, it’s because it’s waiting for something However, a Thread may be awakened at any time, for the wrong reason (or for no reason at all) Therefore, a wait should always be performed within a loop Here’s the idiom: synchronized (obj) { while ( the thing I’m waiting for hasn’t happened ) { obj.wait(); } // Do whatever it was I was waiting to do Also, a wait method can throw an InterruptedException, so you will need to put the above in a try/catch block
7
The Producer-Consumer problem Sometimes you have two independent processes, one producing results, and the other consuming them For example, downloading a file or a Web page You want the process to move along efficiently The Producer shouldn’t have to wait for the Consumer to take something before it can produce another good The Consumer should take things as quickly as it can, pausing only when it needs to wait for the Producer In programming, we often have this problem when dealing with Thread s The data structure we need is a Queue
8
Implementing a Queue We want a Queue that we can use for passing objects from one Thread to another We will define put( object ) and object =get() methods The Queue must be synchronized, because having two different Threads modifying it “at the same time” could be disastrous The Producer Thread needs to wait if (and only if) the Consumer Thread is currently taking something off the queue If the Consumer Thread wants to get something from the Queue, and the Queue is empty, it has to wait for something to be put in the Queue That is, get is a blocking operation In the following code, I’ll use an ArrayList to implement the Queue This is not as efficient as it could be (it’s O(n) ), but it’s fast enough for my purposes
9
Queue code import java.util.ArrayList; public class Queue { ArrayList list = new ArrayList(); public void put(Object obj) { synchronized (list) { list.add(obj); list.notify(); } } public Object get() { try { synchronized (list) { while (list.size() == 0) { list.wait(); } return list.remove(0); } } catch (InterruptedException e) { } } }
10
Two-way communication A Queue is fine if one class is a producer and the other is a consumer However, what if one Thread wants to ask questions of the other Thread? Thread 1: putRequest(request): response = getResponse(); Thread 2: request = getRequest(); response = doSomethingWith(request); putResponse(response); This requires a pair of Queues In my code, I call this a “Channel”
11
Channel (a pair of Queues) public class Channel { Queue request = new Queue(); Queue response = new Queue(); public void putRequest(Object obj) { request.put(obj); } public Object getRequest() { return request.get(); } public void putResponse(Object obj) { response.put(obj); } public Object getResponse() { return response.get(); } }
12
Turn-based play Sometimes we want to coordinate the activities of different Threads One example is a game, where the various players take turns Channel[] channels; // One for each player public void run() { Command request; Object response; while (true) { for (int i = 0; i < channels.length; i++) { do { request = (Command) channels[i].getRequest(); response = doCommand(request); channels[i].putResponse(response); } while (!isAction(request)); } } }
13
Unmonitored Thread methods The following methods can be used without getting a monitor static Thread currentThread() Returns a reference to the currently executing Thread object static void sleep(long ms ) Causes the current Thread to become dormant for (at least) the given number of milliseconds The current Thread does not release any monitors it holds, so other threads waiting for this monitor remain blocked public static void yield() Causes the current Thread to pause and allow other Threads to execute boolean isAlive() Tests if the given Thread is alive void join() Waits for the given Thread to die
14
The End
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.