Crabime Crabime - 29 days ago 10
Java Question

Java program keep infinite loop without any error message

Here i'm learning

volatile
keyword and java memory model, code below:

public class VolatileTest {
public volatile int inc = 0;

public void increase() {
inc++;
}

public static void main(String[] args) {
final VolatileTest test = new VolatileTest();
for(int i=0;i<10;i++){
new Thread(){
public void run() {
for(int j=0;j<10;j++)
test.increase();
};
}.start();
}

while(Thread.activeCount()>1)
Thread.yield();
System.out.println(test.inc);
}
}


what't wrong with it? maybe something caused by the mac os? hope some one help me out?

Answer

This is because your test Thread.activeCount() > 1 will never be false as you have at least 2 threads that will still be running/active in the same group of threads after your threads die, which are:

  1. The main thread (the current one)
  2. The Monitor Ctrl-Break thread

You can check it by calling Thread.currentThread().getThreadGroup().list() to print the list of all the threads that are in the group of the current thread so at worse it should rather be Thread.activeCount() > 2.


But anyway it is not a good practice to rely on Thread.activeCount() for such thing as it is not reliable since it is only an estimate value, you should rather use a CountDownLatch to synchronize your threads as next:

public static void main(String[] args) throws InterruptedException {
    ...
    // CountDownLatch to be decremented 10 times to release awaiting threads
    CountDownLatch latch = new CountDownLatch(10);
    for(int i=0;i<10;i++){
        new Thread(){
            public void run() {
                try {
                    ...
                } finally {
                    // Decrement it as the task is over
                    latch.countDown();
                }

            };
        }.start();
    }
    // Await until the countdown reaches 0
    latch.await();
    System.out.println(test.inc);
}