How to get a the name of the threadgroup a current thread is in

In my main method, I have done the following:

ThreadGroup human = new ThreadGroup("Humans");
Thread s = new Thread(human, new Student(ca));

When I print out the the name of the group the thread is in by System.out.println(s.getThreadGroup().getName()); then it prints out Humans. But when I go to the Student class and do the following: String threadGroupName = this.getThreadGroup().getName(); and print out the String variable, it prints out main. I dont understand this as upon creation of this thread, I have speicified it to be in the Humans thread group so why is it saying it's in the main thread group?

Upvotes: 1

Views: 2659

Answers (2)

Zain Qazi
Zain Qazi

Reputation: 93

s is the new thread you created. Whereas, your Student instance is s.target

When you ran the Thread constructor to create s, you injected the new Runnable (Student instance in your case).

Thread s = new Thread(human, new Student(ca));

s is thread-x and Student is thread-y. They are separate instances.

s.target is the new Runnable Student you had created.

Hope this helps.

If you want to have the same thread group, you have to pass the "Humans" ThreadGroup into the Student thread. Try this:

public class ThreadGroups {

    public static void main(String[] args){
        ThreadGroup human = new ThreadGroup("Humans");
        Thread s1 = new Student(human, "studentThread");
        Thread s = new Thread(human, s1);
        System.out.println(s.getThreadGroup().getName());
        System.out.println(s1.getThreadGroup().getName());
        s.start();
    }

    static class Student extends Thread {
        @Override
        public void run() {
            System.out.println(this.getThreadGroup().getName());
        }

        public Student(ThreadGroup group, String name) {
            super(group, name);
        }

        public Student() {
        }
    }
}

Upvotes: 1

Lothar
Lothar

Reputation: 5449

I assume Student extends from Thread, otherwise there wouldn't be a getThreadGroup method to call. The reason why you get main as result is that you haven't passed human to your instance of Student, so that thread is assigned to the main-group.

Here is an example class that should show you the effect:

public class ThreadGroupTest {

    public final static void main(String[] args) throws Exception{
        ThreadGroup human = new ThreadGroup("Humans");
        Student student = new Student(null);
        Thread s = new Thread(human, student);
        synchronized(student) {
            s.start();
            student.wait(1000);
        }
        System.out.println(s.getThreadGroup().getName());
        student.printThisThreadGroup();
        student.printCurrentThreadGroup();
        synchronized(student) {
            student.killed = true;
            student.notifyAll();
        }

    }

    static class Student extends Thread {
        Student(ThreadGroup group) {
            super(group, (Runnable) null);
        }

        boolean killed;

        @Override
        public void run() {
            System.out.println("running in group '" + Thread.currentThread().getThreadGroup().getName() + "'");
            try {
                while (!killed) {
                    synchronized(this) {
                        notifyAll();
                        wait(1000);
                    }
                }
            }
            catch(Exception e) {
                // ignore
            }

        }

        public void printThisThreadGroup() {
            System.out.println("this.getThreadGroup: " + this.getThreadGroup().getName());
        }

        public void printCurrentThreadGroup() {
            System.out.println("CurrentThread: " + Thread.currentThread().getThreadGroup().getName());
        }

    }
}

The code is a more complete example of your implementation, you can see a constructor of student that takes a ThreadGroup as parameter which currently is null. That's the equivalent of using the default-constructor which I assume you used (it's not part of your example code).

When executing this code you get the following output:

running in group 'main'
Humans
this.getThreadGroup: main
CurrentThread: main

If you change null to human the output will change to the following:

running in group 'Humans'
Humans
this.getThreadGroup: Humans
CurrentThread: main

Here this.getThreadGroup provides you with the correct group but it's not the final answer, yet. Instead of extending from Thread you should implement Runnable and pass that to a newly instantiated Thread I suppose you did it because of your requirement to get the thread's ThreadGroup, but that's not required as you can see in Student's run-method how you can achieve that by calling Thread.currentThread() returning the thread you're currently in. You can also see that using this still is a bit tricky, because you still get main as result if you call that method from a different method (the main method here) running in a different thread (again the main-thread leading to main as result in the last line of the four output lines.

Upvotes: 0

Related Questions