Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is 'synchronized' really just syntactic sugar?

I am new to multithreading, and I wrote this code which prints the numbers 1-10000 by having concurrently running threads increment and print a variable.

Here's the code I'm using:

package threadtest;

public class Main{

    static int i=0;
    static Object lock=new Object();

    private static class Incrementer extends Thread{

        @Override
        public void run(){
            while (true){
                synchronized(lock){
                        if (i>=10000)
                            break;
                        i++;
                        System.out.println(i);
                }
            }               
        }
    }


    public static void main(String[] args) {
        new Incrementer().start();
        new Incrementer().start();
        new Incrementer().start();
        new Incrementer().start();
        new Incrementer().start();
        new Incrementer().start();
    }
}

This works - I wrote up a test program to check the output, and the numbers printed are exactly 1-10000 in order.

My question is this: I've heard that synchronized is only syntactic sugar. But I can't seem to achieve a successful result without using it. What am I missing?

like image 302
Cam Avatar asked Jun 26 '10 16:06

Cam


2 Answers

synchronized is by no means syntactic sugar for anything. There is no way to work locks in Java without using the synchronized keyword.

Where there is "syntactic sugar" of a sort in locks in Java is that synchronized can apply both to blocks (as you've done it above) and to whole methods. The following two methods are roughly equivalent in semantics:

synchronized void method1() {
  // ... do stuff ...
}

void method2() {
  synchronized(this) {
    // ... do stuff ...
  }
}

So why would you want to do the second version instead of the first?

  • Synchronized method invocations are far slower than plain old method invocations, like by about an order of magnitude. If your synchronized code isn't guaranteed to always execute (say it's in a conditional), then you probably don't want to synchronize the whole method.
  • Synchronized methods hold locks for longer than synchronized blocks (because of all the method setup/tear down code). The second method above will hold the lock for less time because the time spent setting up and tearing down the stack frame won't be locked.
  • You can have much finer control over exactly what you're locking if you go with the synchronized blocks.
  • (Courtesy of starblue) Synchronized blocks can use objects other than this for locking which gives you more flexible locking semantics.
like image 132
JUST MY correct OPINION Avatar answered Nov 02 '22 10:11

JUST MY correct OPINION


It sounds like your sources are just wrong. The syncrhonized keyword is important to use - and use properly - when writing thread-safe code. And it sounds like your own experiments bear this out.

For more on synchronization in Java:

Java Synchronized Methods

Java Locks and Synchronized Statements

like image 37
Isaac Truett Avatar answered Nov 02 '22 09:11

Isaac Truett