Gleb Danichev
Gleb Danichev

Reputation: 21

Setting variable in one thread by another

Why the pool does not set to 5 in the f() method that is called by another thread?

public class Main {        
        private static int pool = 5;        
        public static void main(String... arg) {        
            Th t = new Th();
            Thread thread = new Thread(t);
            thread.start();

            while (true) {        
               if (pool >= 0)
                    System.out.println(pool--);
            }       
        }

        static void f() {
            pool = 5;
            System.out.println("main.Main.f:pool=" + pool);
        }       
    }
    class Th implements Runnable {        
        @Override
        public void run() {
            while (true) {
                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                Main.f();        
            }
        }
    }

Output:

5
4
3
2
1
0
main.Main.f:pool=5
main.Main.f:pool=5
main.Main.f:pool=5
main.Main.f:pool=5

I can fix it declaring pool as volatile but I can't get why it works 8(

Upvotes: 1

Views: 81

Answers (2)

erickson
erickson

Reputation: 269687

A value written by one thread won't always be read by another. There needs to be a "memory barrier" in order to guarantee visibility, and declaring a field as volatile is one way to obtain that guarantee.

Loosely speaking, you have to ask for visibility if you want it, otherwise the runtime is free to skip it as an optimization. For example it might use a register to store the main thread's value of pool instead of updating a field in an object out in the heap. Your code doesn't indicate that other threads should be able to tell the difference, so the runtime is allowed to perform the optimization.

Upvotes: 2

WestCoastProjects
WestCoastProjects

Reputation: 63062

The behavior makes sense: your main() has no sleep() in it - so it is able to execute the decrement five times in quick succession. Then after 1000 milliseconds - and every second after - the f() is called to set the pool to 5.

Upvotes: 0

Related Questions