Title: Developing MultiThreaded Application (Part III)
1Developing 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).
2Waiting 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?
3Example 1 Waiting for Synchronized Data
class Producer implements Runnable Q q Thread
thnew Thread(this, "Producer") Producer(Q
q) this.qq th.start() public void
run() int i0 while(true) q.put(i)
class Q int n boolean valueSetfalse
synchronized int get() if(!valueSet)
trywait()catch(InterruptedException e)
System.out.println("Got"n)
valueSetfalse notify() return
n synchronized void put(int n)
if(valueSet) trywait()catch(InterruptedExce
ption e) this.nn valueSettrue
System.out.println("Put"n) notify()
consumer
Producer
4Example 1 Waiting for Synchronized Data (Contd)
class Consumer implements Runnable Q q Thread
thnew Thread(this, "Consumer") Consumer(Q
q) this.qq th.start() public void
run() while(true) q.get()
public class PCproblem public static void
main(String s) Q qnew Q() new
Producer(q) new Consumer(q) System.out.println
(press Conrl-C to stop.")
5Thread Groups
Guidelines for using thread groups 1- Use the
ThreadGroup constructor to construct a thread
group Construct a thread group using the
ThreadGroup constructorThreadGroup g new
ThreadGroup("timer thread group") This creates a
thread group g namedthread group. The name is a
string and must be unique. 2- Place a thread in a
thread group using the Thread constructorThread
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. NoteYou have to start
the each thread individually. There is no start()
method in ThredGroup!!!
6Creating 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.
7Thread Groups A Pictorial View
8Example 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
Threadtop.activeCount() top.enumerate(theTh
reads) for (int i 0 i lt
theThreads.length i)
System.out.println(theThreadsi)
- 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).
9Daemon 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 programs 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.
10Using 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.
11Using Threads with Swing GUI Components (Contd)
- 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. - Well exemplify these issues in the lab.