Reputation: 91
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
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
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