/**
 * 最近在学习线程组方面的东西,运行了《thinking in java》的一个示例程序,程序如下:
 * 
 * @author zhaoke
 * 
 */
public class TestAccess {
    public static void main(String[] args) {
        ThreadGroup x = new ThreadGroup("X");// 生成一个单链关系的三个线程群组
        ThreadGroup y = new ThreadGroup(x, "Y");
        ThreadGroup z = new ThreadGroup(y, "Z");
        new TestThread1(x, "one");// 让线程one属于最上层组群
        new TestThread2(z, "two");// 让线程two属于最下层组群
    }
}class TestThread1 extends Thread {
    private int i;    public TestThread1(ThreadGroup g, String name) {
        super(g, name);
    }    protected void f() {// 修改自身的属性
        i++;
        System.out.println(getName() + " f()");
    }
}class TestThread2 extends TestThread1 {
    public TestThread2(ThreadGroup g, String name) {
        super(g, name);
        start();
    }    public void run() {
        ThreadGroup threadGroup = getThreadGroup().getParent().getParent();// 得到其所在线程组群数的最上层的组群
        threadGroup.list();// 打印出这个组群的详细信息
        Thread[] gAll = new Thread[threadGroup.activeCount()];
        threadGroup.enumerate(gAll);// 得到这个组群及其所有子群的所有active线程的reference
        for (int i = 0; i < gAll.length; i++) {
            gAll[i].setPriority(Thread.MIN_PRIORITY);
            ((TestThread1) gAll[i]).f();
        }
        threadGroup.list();
    }
} // /:~/*******************************************************************************
 * 我运行了这个程序,但是并没有书上预料的结果:抛出了空指针异常。运行结果如下:
 * 
 * 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 com.zhaoke.j2seprograme.tijcode.c14.TestThread2.run(TestAccess.java:44)
    
    
 * 
 *   我想应该是Thread[] gAll里面有null了。
 *   打印结果是gAll中只有一个线程对象。我看了jdk帮助文档,enumerate()有关功能说明如下:Copies into the
 *   specified array every active thread in this thread group and its subgroups.
 *   按照文挡的说明 该函数应该能够把线程one复制到数组gAll中。请能者指教
 * 
 * 
 * 
 */

解决方案 »

  1.   

    new TestThread1(x, "one"); 根本就没来得及((TestThread1) gAll[i]).f();就被回收了.所以为null.//程序可以这样写public class TestAccess {
        public static void main(String[] args)
        {
            ThreadGroup x = new ThreadGroup("X");// 生成一个单链关系的三个线程群组
            ThreadGroup y = new ThreadGroup(x, "Y");
            ThreadGroup z = new ThreadGroup(y, "Z");
            
            new TestThread2(z, "two");// 让线程two属于最下层组群
            new TestThread1(x, "one");// 让线程one属于最上层组群
        }
    }class TestThread1 extends Thread {
        private int i;
        public static boolean flag = true;    public TestThread1(ThreadGroup g, String name) 
        {
            super(g, name);
            start();
        }    protected void f() 
        { // 修改自身的属性
            i++;
            System.out.println(getName() + " f()");
        }
        
        public void run()
        {
         while(TestThread1.flag)
         {
    for (long i = 0 ; i < 100000; i ++ );
         }
        }
    }class TestThread2 extends TestThread1 
    {
        public TestThread2(ThreadGroup g, String name) 
        {
            super(g, name);
            //start();
        }    public void run() 
        {
            ThreadGroup threadGroup = getThreadGroup().getParent().getParent();// 得到其所在线程组群数的最上层的组群
            
            threadGroup.list(); // 打印出这个组群的详细信息
            
            
            Thread[] gAll = new Thread[threadGroup.activeCount()];
            
            threadGroup.enumerate(gAll); // 得到这个组群及其所有子群的所有active线程的reference
            
            for (int i = 0; i < gAll.length; i++)
            {
                gAll[i].setPriority(Thread.MIN_PRIORITY);
                ((TestThread1) gAll[i]).f();
                
            }
            
            threadGroup.list();
            
            TestThread1.flag = false;
        }
    }
      

  2.   

    java.lang.ThreadGroup[name=X,maxpri=10]
        java.lang.ThreadGroup[name=Y,maxpri=10]
            java.lang.ThreadGroup[name=Z,maxpri=10]
                Thread[two,5,Z]
    two f()
    java.lang.ThreadGroup[name=X,maxpri=10]
        java.lang.ThreadGroup[name=Y,maxpri=10]
            java.lang.ThreadGroup[name=Z,maxpri=10]
                Thread[two,1,Z]
    我机器上运行的结果
      

  3.   

    虚心请教yuzl32(Hello!有酒醉) :
      还是不太明白你的意思。new TestThread1(x, "one"); 为什么会被释放呢?是因为它的run什么也没做吗?可是它的start函数就没有被调用啊!
      还有一个问题是sun对ThreadGroup是这样说明的:A thread is allowed to access information about its own thread group, but not to access information about its thread group's parent thread group or any other thread groups.那么线程two为什么能改变其上层ThreadGroup中的线程one的属性呢?