110 likes | 208 Views
Developing MultiThreaded Application (Part III). Overview Waiting for Synchronized Data. Creating Thread Groups. Daemon Threads. Using Threads with Swing GUI Components: Things to Note. Preview: Sorting Algorithms (Part I). Waiting for Synchronized Data.
E N D
Developing MultiThreaded Application (Part III) Overview • Waiting for Synchronized Data. • Creating Thread Groups. • Daemon Threads. • Using Threads with Swing GUI Components: Things to Note. • Preview: Sorting Algorithms (Part I). Threads (Extra Lecture)
Waiting for Synchronized Data • We note that each method which may potentially cause a race condition (i.e. may be called by different threads before completion) should be declared synchronized. • We also note that there are cases when synchronization is not enough; we must call some methods of the Thread class to help the situation. We exemplify: • The classic example is the “producer/consumer” problem within which a producer and a consumer share data. • When a thread arrives at a synchronized method and finds that it has arrived too early, the thread should wait (call the wait() method of Thread). Note that either the producer or the consumer thread might arrive too early. • When a thread finished processing synchronized data, the thread calls notify()/notifyAll() to tell other threads to stop waiting. • Using wait() and notify()/notifyAll() methods producer/consumer problems can be implemented properly. • When a thread calls wait() inside a synchronized method/block, another method is allowed to access the code. • What happens when an exception is thrown while a synchronized method is being executed? Threads (Extra Lecture)
Example 1: Waiting for Synchronized Data class Producer implements Runnable{ Q q; Thread th=new Thread(this, "Producer"); Producer(Q q){ this.q=q; th.start(); } public void run(){ int i=0; while(true){ q.put(i++); } } } class Q { int n;boolean valueSet=false;synchronized int get() {if(!valueSet) try{wait();}catch(InterruptedException e){ } System.out.println("Got:"+n); valueSet=false;notify();return n; } synchronized void put(int n) {if(valueSet) try{wait();}catch(InterruptedException e){}this.n=n; valueSet=true; System.out.println("Put:"+n);notify();} } consumer Producer Threads (Extra Lecture)
Example 1: Waiting for Synchronized Data (Cont’d) class Consumer implements Runnable{ Q q; Thread th=new Thread(this, "Consumer"); Consumer(Q q){ this.q=q; th.start(); } public void run(){ while(true){ q.get(); } } } public class PCproblem{ public static void main(String[] s){ Q q=new Q(); new Producer(q); new Consumer(q); System.out.println(“press Conrl-C to stop."); } } Threads (Extra Lecture)
Thread Groups Guidelines for using thread groups: 1- Use the ThreadGroup constructor to construct a thread group: Construct a thread group using the ThreadGroup constructor:ThreadGroup g = new ThreadGroup("timer thread group"); This creates a thread group g named”thread group”. The name is a string and must be unique. 2- Place a thread in a thread group using the Thread constructor:Thread t = new Thread(g, new ThreadClass(), "This thread"); The statement new ThreadClass() creates a runnable instance for the ThreadClass. You can addd a thread group under another thread group to form a tree in which every thread group except the initial one has a parent. 3- To find out how many threads in a group are currently running, use the activeCount( )method: System.out.println("The number of “ + “ runnable threads in the group+ g.activeCount()); 4- Each thread belongs to a thread group.By default, a newly created thread becomes a member of the current thread group that spawned it. To find which group a thread belongs to, use the getThreadGroup() method. Note:You have to start the each thread individually. There is no start() method in ThredGroup!!! Threads (Extra Lecture)
Creating a Thread Group • Within your Java program, there may be times when you have multiple threads working on a similar task. In such cases, you may find it convenient to group threads by type, which then allows you to manipulate the group as a single entity. • For example, suppose you have a number of animation threads that you need to pause based on user input. You can group these threads into a single-thread group and then suspend all with one function call. • Class ThreadGroup has methods for creating and manipulating thread groups. This class provides the constructors: • public ThreadGroup(String groupName) • Constructs a ThreadGroup with name groupName. • public ThreadGroup(ThreadGroup parent, String child) • Constructs a child ThreadGroup of parent called child • The second constructor above shows that a thread group can be the parent thread group to a child thread group. • The following example demonstrate the use of some methods of the ThreadGroup class. Threads (Extra Lecture)
Thread Groups: A Pictorial View Threads (Extra Lecture)
Example 2: Printing All Progams’ Threads public class AllThreads { public static void main(String[] args) { ThreadGroup top = Thread.currentThread().getThreadGroup(); while(true) { if (top.getParent() != null) top = top.getParent(); else break; } Thread[] theThreads = new Thread[top.activeCount()]; top.enumerate(theThreads); for (int i = 0; i < theThreads.length; i++) { System.out.println(theThreads[i]); }} } • This program prints all active threads. • It uses the getThreadGroup() method of java.lang.Thread and getParent() method of java.lang.ThreadGroup to walk up to the top level thread group; then using enumerate to list all the threads in the main thread group and its children (which covers all thread groups). Threads (Extra Lecture)
Daemon Threads • A daemon thread is a thread that runs for the benefit of other threads. A typical example of a daemon thread in Java is the garbage collector. • Daemon threads run in the background (I.e., when processor time is available that would otherwise go to waste). • Unlike other threads, if daemon threads are the only threads that are running, the program will exit because the daemons have no other threads to serve. Non-daemon threads are conventional user threads. • Depending on your program’s purpose, there may be times when you need to create your own daemon threads. In such cases you use the method call myThread.setDaemon(true) to designate myThread as daemon. • If a thread is to be a daemon, it must be set as such before its start() method is called or an IllegalThreadStateException is thrown. Threads (Extra Lecture)
Using Threads with Swing GUI Components • Having demonstrated the use of the synchronized keyword and the wait(), notify() methods, we are now ready to comment on threads and swing components. • Note that event-handling code executes in a single thread, the event-dispatching thread. This ensures that each event handler will finish executing before the next one executes. • For instance, while the actionPerformed() method is executing, the program's GUI is frozen -- it won't repaint, respond to mouse clicks or respond to any other event. • This suggests that the code in event handlers should execute very quickly otherwise your program's perceived performance will be poor. • What happens in a program in which one event handler calls an infinite method? • Most methods in the Java Swing API are not thread-safe and, therefore, care should be taken when using these methods. • For this reason Swing components can be accessed by only one thread at a time, generally, the event-dispatching thread. However, a few operations are guaranteed to be thread-safe. Threads (Extra Lecture)
Using Threads with Swing GUI Components (Cont’d) • Therefore, if your program creates threads to perform tasks that affect the GUI, or if it manipulates the already-visible GUI in response to anything different from the standard events, then things can go wrong. • To access to a GUI from outside event-handling or painting code, you can use the invokeLater() or invokeAndWait() methods of the SwingUtilities class. • An applet program that construct its GUI in the init() method is said to be doing it in “the right way”. This is because existing browsers don't paint an applet until after its init() and start() methods have been called. • Likewise an application program that creates its GUI in the main() method (creates the GUI, adds components to it and show()s it only) is said to be doing GUI in “the right way”. • A program that creates and refers to its GUI the right way, might not need to worry about safety issues due to threads. • We’ll exemplify these issues in the lab. Threads (Extra Lecture)