Steven Levine
Steven Levine
1 min read

Tags

In Java, access to shared resources can be controlled by using synchronized methods. An instance method is declared to be a synchronized method by adding the modifier synchronized to its declaration. For example:

public class Foo {
    synchronized void bar() { ... }
}

The meaning is that only one synchronized method can be active in an object at any given time. If a thread tries to call a synchronized method, and if that method or some other synchronized method in the same object is already being executed by a different thread, then the thread will have to wait until that other thread has finished executing its method. This is all handled automatically by the system. All you have to do is declare the methods to be synchronized.

If all access to shared resources is done in synchronized methods, then you can be sure that at any given time, only one thread will ever have access to those resources. You can be sure that one thread will have a chance to finish with a resource before another thread will have a chance to use it.

Under the covers, the concept of synchronization is simple: when a method is declared as synchronized, it must have a token, which we can call a lock. Once the method has aquired the lock (you can also say the lock has been checked out or grabbed), it executes the method and releases (we may also say returns) the lock once the method has finished. No matter how the method returns, even if via an Exception, the lock is then released. There is only one lock per object, so if two threads try to call the method at the same time, only one thread will be allowed to invoke the method.

On the other hand, if you have two seperate instances of the same object. I.e.,

Foo f1 = new Foo();
Foo f2 = new Foo();
f1.bar();
f2.bar()

These two calls will be invoked at the same time, since there is only one lock per object.