Recent top five:
Java.next -- Four languages that represent the future of Java
Blogger Stuart Halloway has begun a series of posts on trends that point to the future of the Java platform. In his first
post, he compares Clojure, Groovy, JRuby, and Scala -- four wildly different languages that nonetheless all play together
in the JRE. Find out what unites these languages and what they can tell us about the future of Java-based development ...
| Enterprise AJAX - Transcend the Hype |
| Memory Analysis in Eclipse |
| Oracle Compatibility Developer's Guide |
| Memory Analysis in Eclipse |
Page 3 of 6
Listing 3: InterruptThreadGroup.java
// InterruptThreadGroup.java
class InterruptThreadGroup
{
public static void main (String [] args)
{
MyThread mt = new MyThread ();
mt.setName ("A");
mt.start ();
mt = new MyThread ();
mt.setName ("B");
mt.start ();
try
{
Thread.sleep (2000); // Wait 2 seconds
}
catch (InterruptedException e)
{
}
// Interrupt all methods in the same thread group as the main
// thread
Thread.currentThread ().getThreadGroup ().interrupt ();
}
}
class MyThread extends Thread
{
public void run ()
{
synchronized ("A")
{
System.out.println (getName () + " about to wait.");
try
{
"A".wait ();
}
catch (InterruptedException e)
{
System.out.println (getName () + " interrupted.");
}
System.out.println (getName () + " terminating.");
}
}
}
The main thread creates and starts threads A and B before sleeping for 2,000 milliseconds to give A and B a chance to wait. Upon waking, the main thread assumes A and B are waiting, and executes Thread.currentThread ().getThreadGroup ().interrupt (); to interrupt those threads. Because A and B execute in a synchronized context, one thread will throw an InterruptedException object and finish its processing before the other thread does the same. When run, InterruptThreadGroup produces the following output (for one invocation):
A about to wait. B about to wait. A interrupted. A terminating. B interrupted. B terminating.
A is interrupted and terminates before B is interrupted and terminates.
You'll occasionally want to enumerate all threads or subgroups that comprise a thread group. The next section explores that activity.
Part 1 introduced you to Thread's activeCount() and enumerate(Thread [] thdarray) methods. activeCount() calls ThreadGroup's int activeCount() method via the current thread's group reference to return an estimate of the active threads in the current thread's group
and subgroups. enumerate(Thread [] thdarray) calls ThreadGroup's int enumerate(Thread [] thdarray) method via the current thread's group reference. enumerate(Thread [] thdarray) is just one of four enumeration methods in ThreadGroup:
int enumerate(Thread [] thdarray) copies into thdarray references to every active thread in the current thread group and all subgroups.
int enumerate(Thread [] thdarray, boolean recurse) copies into thdarray references to every active thread in the current thread group only if recurse is false. Otherwise, this method includes active threads from subgroups.
int enumerate(ThreadGroup [] tgarray) copies into tgarray references to every active subgroup in the current thread group.
int enumerate(ThreadGroup [] tgarray, boolean recurse) copies into tgarray references to every active subgroup in the current thread group only if recurse is false. Otherwise, this method includes all active subgroups of active subgroups, active subgroups of active subgroups
of active subgroups, and so on.
You can use ThreadGroup's activeCount and enumerate(Thread [] thdarray) methods to enumerate all program threads. First, you find the system thread group. Then you call ThreadGroup's activeCount() method to retrieve an active thread count for array-sizing purposes. Next, you call ThreadGroup's enumerate(Thread [] thdarray) method to populate that array with Thread references, as Listing 4 demonstrates:
Listing 4: EnumThreads.java
// EnumThreads.java
class EnumThreads
{
public static void main (String [] args)
{
// Find system thread group
ThreadGroup system = null;
ThreadGroup tg = Thread.currentThread ().getThreadGroup ();
while (tg != null)
{
system = tg;
tg = tg.getParent ();
}
// Display a list of all system and application threads, and their
// daemon status
if (system != null)
{
Thread [] thds = new Thread [system.activeCount ()];
int nthds = system.enumerate (thds);
for (int i = 0; i < nthds; i++)
System.out.println (thds [i] + " " + thds [i].isDaemon ());
}
}
}
When run, EnumThreads produces the following output (on my platform):
Thread[Reference Handler,10,system] true Thread[Finalizer,8,system] true Thread[Signal Dispatcher,10,system] true Thread[CompileThread0,10,system] true Thread[main,5,main] false
Apart from a main thread, all other threads belong to the system thread group.
| Tip |
|---|
You can easily determine a thread group's parent group by calling ThreadGroup's ThreadGroup getParent() method. For all thread groups, save system, this method returns a nonnull reference. For system, this method returns null. You can also find out if a thread group is the parent, grandparent, and so forth of another thread
group by calling ThreadGroup's boolean parentOf(ThreadGroup tg) method. That method returns true if a thread, whose reference you use to call parentOf(ThreadGroup tg), is a parent (or other ancestor) of the group that tg references—or is the same group as the tg-referenced group. Otherwise, the method returns false.
|
Volatility, that is, changeability, describes the situation where one thread changes a shared field variable's value and another thread sees that change. You expect other threads to always see a shared field variable's value, but that is not necessarily the case. For performance reasons, Java does not require a JVM implementation to read a value from or write a value to a shared field variable in main memory, or object heap memory. Instead, the JVM might read a shared field variable's value from a processor register or cache, collectively known as working memory. Similarly, the JVM might write a shared field variable's value to a processor register or cache. That capability affects how threads share field variables, as you will see.