Pages

Thursday, October 13, 2011

Synchronization on instance vs static method

Simple the difference is that synchronizing on instance method is like writing synchronized (this) and synchronizing on static method is like writing synchronized (FooBar.class).
If you want not so simple explanation, here it is:

    public static void main(String[] args) {
        new FooBar().instanceFoo(true);
        //This is extremely bad and not the thing that should be used in  reality. In fact it produces
        //compiler warning. Use Foobar.staticFoo(true) instead.
        new FooBar().staticFoo(true);
    }

    private static class FooBar {
        public static synchronized void staticFoo(boolean recursive) {
            Thread thread = new Thread(new StaticRunner(recursive));
            thread.start();
            try {
                thread.join();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }

        public synchronized void instanceFoo(boolean recursive) {
            Thread thread = new Thread(new InstanceRunner(recursive));
            thread.start();
            try {
                thread.join();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }

    private static class StaticRunner implements Runnable {
        private final boolean recursive;

        public StaticRunner(boolean recursive) {
            this.recursive = recursive;
        }

        @Override
        public void run() {
            if (recursive) {
                //This is extremely bad and not the thing that should be used in  reality. In fact it produces
                //compiler warning. Use Foobar.staticFoo(false) instead.
                new FooBar().staticFoo(false);
                System.out.println("This will never be printed");
            } else {
                System.out.println("Internal static run - this will never be printed too");
            }
        }

    }

    private static class InstanceRunner implements Runnable {
        private final boolean recursive;

        public InstanceRunner(boolean recursive) {
            this.recursive = recursive;
        }

        @Override
        public void run() {
            if (recursive) {
                new FooBar().instanceFoo(false);
            } else {
                System.out.println("Internal instance run");
            }
        }

    }

No comments:

Post a Comment