A tiny program as the following (from Bruce Eckel's Thinking in Java, 2nd Ed., Chapter 14)
public class TestAccess { public static void main(String[] args) { ThreadGroup x = new ThreadGroup("x"), y = new ThreadGroup(x, "y"), z = new ThreadGroup(y, "z"); Thread one = new TestThread1(x, "one"), two = new TestThread2(z, "two"); } }
class TestThread1 extends Thread { private int i; TestThread1(ThreadGroup g, String name) { super(g, name); } void f() { i++; // modify this thread System.out.println(getName() + " f()"); } }
class TestThread2 extends TestThread1 { TestThread2(ThreadGroup g, String name) { super(g, name); start(); } public void run() { ThreadGroup g = getThreadGroup().getParent().getParent(); g.list(); Thread[] gAll = new Thread[g.activeCount()]; g.enumerate(gAll); for(int i = 0; i < gAll.length; i++) { gAll.setPriority(Thread.MIN_PRIORITY); ((TestThread1)gAll).f(); } g.list(); } }
The book says the output of this program should be: java.lang.ThreadGroup[name=x,maxpri=10] Thread[one,5,x] java.lang.ThreadGroup[name=y,maxpri=10] java.lang.ThreadGroup[name=z,maxpri=10] Thread[two,5,z] one f() two f() java.lang.ThreadGroup[name=x,maxpri=10] Thread[one,1,x] java.lang.ThreadGroup[name=y,maxpri=10] java.lang.ThreadGroup[name=z,maxpri=10] Thread[two,1,z]
But the output of my running it on Java 2 SE V1.4.1 is like this: java.lang.ThreadGroup[name=x,maxpri=10] Thread[one,5,x] java.lang.ThreadGroup[name=y,maxpri=10] java.lang.ThreadGroup[name=z,maxpri=10] Thread[two,5,z] two f() java.lang.NullPointerException at TestThread2.run(TestAccess.java:40