Thread behaviour

S

stixwix

Hi,

If I have a program which starts 100 threads in main:

for (int i = 0; i < 100; i++){
String name = Integer.toString(i);
Thread temp = new Thread(new Worker());
temp.setName(name);
temp.start();
}

where the Worker's run method just prints out the threads name, then in
this configuration I see about the last 50 threads print their message.

I initially thought that this is because the thread object referenced
by temp goes out of scope each time round the loop and so could be
garbage collected. But perhaps the fact that they are all in the same
thread group keeps them in scope?

If I use a CyclicBarrier and wait in main after the for loop (and force
each thread to wait at the end of its run method) then all threads are
seen to run.

I know this is a bit of a contrived example but am just interested
whether the thread objects are subject to GC the same as any other if
they can't be seen by main.

Thanks,
Andy
 
O

O.L.

Après mure réflexion, stixwix a écrit :
where the Worker's run method just prints out the threads name, then in
this configuration I see about the last 50 threads print their message.

Are you sure it's a good way to look at the threads activity ?
Try using an "int" counter, each thread increments the global static
counter, and then see what happens.

Bye
 
M

Matt Humphrey

stixwix said:
Hi,

If I have a program which starts 100 threads in main:

for (int i = 0; i < 100; i++){
String name = Integer.toString(i);
Thread temp = new Thread(new Worker());
temp.setName(name);
temp.start();
}

where the Worker's run method just prints out the threads name, then in
this configuration I see about the last 50 threads print their message.

I initially thought that this is because the thread object referenced
by temp goes out of scope each time round the loop and so could be
garbage collected. But perhaps the fact that they are all in the same
thread group keeps them in scope?

If I use a CyclicBarrier and wait in main after the for loop (and force
each thread to wait at the end of its run method) then all threads are
seen to run.

I know this is a bit of a contrived example but am just interested
whether the thread objects are subject to GC the same as any other if
they can't be seen by main.

Threads are not eligible for GC simply because there are no references to
them from the main thread. If only some of the threads are running to
completion I would think it's because your main thread exits before they
finish and they are daemon threads. A java program will exit only when all
non-daemon threads have finished--running daemon threads are discarded. A
thread is a daemon thread by default if its parent is. Otherwise it can be
set to be daemon with setDaemon(true). The main thread is a non-daemon
thread.

Your message suggests that you're running non-daemon threads from the
non-daemon main thread, so I would expect all your threads to run to
completion (and they do so when I try it) so there may be something relevant
in the code you havn't shown.

When I run the code below (java Test daemon), I get a random number of
threads completing. If I run plain (java Test) I get all the threads
running to completion. As you found out above, if the main thread waits for
the threads to complete, they will all run to completion. (You may need to
tune the sleep parameter below to see how many get to run.)

public class Test {
public static final void main (String args []) {
Runnable task = new Runnable () {
public void run () {
for (int i = 0; i < 100; ++i) {
Thread t = new Thread (new Worker ());
t.setName ("Thread-" + i);
t.start ();
}
}
};

if ( (args.length > 0) && (args[0].equalsIgnoreCase ("daemon") ) ) {
Thread t = new Thread (task);
t.setDaemon (true);
t.start ();
try {Thread.sleep(100);} catch (InterruptedException ex)
{ ex.printStackTrace (); }

} else {
task.run ();
}
}
}
class Worker implements Runnable {
public void run () {
System.out.println (Thread.currentThread().getName());
}
}

Cheers,
Matt Humphrey (e-mail address removed) http://www.iviz.com/
 
S

stixwix

Ah, apologies....the explanation lies in my not reading the output
properly!
I was running it as a JUnit test and saw the output in Eclipse:

Time: 0.016
OK (1 test)

half way through and assumed that this was the test starting point. Of
course, this got written because main completed and every thread did
indeed write to stdout.
Thanks for your help....
Andy
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,056
Latest member
GlycogenSupporthealth

Latest Threads

Top