Thread Synchronization

In this chapter you will learn:

  1. What is synchronization and why we need it
  2. Synchronized Methods
  3. synchronized Statement

What is synchronization

When two or more threads need access to a shared resource, only one thread can access the resource at a time. The process is called synchronization.

The following code shows an example of deadlock. The two threads are waiting for the same resoures.

public class Main {
  private static Object lock1 = new Object();
  private static Object lock2 = new Object();
/*  j a  v a 2  s.  c  o m*/
  public static void main(String[] args) {
    Thread thdA = new Thread(new Runnable() {
      @Override
      public void run() {
        while (true)
          synchronized (lock1) {
            synchronized (lock2) {
              System.out.println("first thread in instanceMethod1");
            }
          }
      }
    });
    
    Thread thdB = new Thread(new Runnable() {
      @Override
      public void run() {
        while (true)
          synchronized (lock2) {
            synchronized (lock1) {
              System.out.println("second thread in instanceMethod2");
             }
          }
      }
    });
    thdA.start();
    thdB.start();
  }
}

Synchronized Methods

You restrict the access to only one thread at a time by preceding call()'s definition with the keyword synchronized:

class Shared {// j  ava  2s  .  co m
  synchronized void call(String msg) {
    System.out.println("Start" );
    System.out.println(msg);
    try {
      Thread.sleep(1000);
    } catch (InterruptedException e) {
      System.out.println("Interrupted");
    }
    System.out.println("end");
  }
}

class Caller implements Runnable {
  String msg;
  Shared target;
  Thread t;

  public Caller(Shared targ, String s) {
    target = targ;
    msg = s;
    t = new Thread(this);
    t.start();
  }

  public void run() {
    target.call(msg);
  }
}

public class Main {
  public static void main(String args[]) {
    Shared target = new Shared();
    Caller ob1 = new Caller(target, "A");
    Caller ob2 = new Caller(target, "B");

    try {
      ob1.t.join();
      ob2.t.join();
    } catch (InterruptedException e) {
      System.out.println("Interrupted");
    }
  }
}

synchronized Statement

You put calls to the methods defined by this class inside a synchronized block. This is the general form of the synchronized statement:

synchronized(object) { 
// statements to be synchronized 
}

Here, object is a reference to the object being synchronized. A synchronized block ensures that a call to a method occurs only after the current thread has successfully entered object's monitor.

Here is an alternative version of the preceding example, using a synchronized block within the run() method:

class Share {/* j  a va2s  .co  m*/
  void call(String msg) {
    System.out.println("start");
    System.out.println(msg);
    try {
      Thread.sleep(1000);
    } catch (InterruptedException e) {
      System.out.println("Interrupted");
    }
    System.out.println("end");
  }
}

class Caller implements Runnable {
  String msg;
  Share target;
  Thread t;

  public Caller(Share targ, String s) {
    target = targ;
    msg = s;
    t = new Thread(this);
    t.start();
  }

  public void run() {
    synchronized (target) { // synchronized block
      target.call(msg);
    }
  }
}

public class Main {
  public static void main(String args[]) {
    Share target = new Share();
    Caller ob1 = new Caller(target, "A");
    Caller ob2 = new Caller(target, "B");
    try {
      ob1.t.join();
      ob2.t.join();
    } catch (InterruptedException e) {
      System.out.println("Interrupted");
    }
  }
}

Next chapter...

What you will learn in the next chapter:

  1. Solve the producer and consumer problem
Home » Java Tutorial » Thread
Thread introduction
Thread Name
Thread Main
Thread sleep
Thread Creation
Thread join and is alive
Thread priorities
Thread Synchronization
Interthread Communication
Thread Step
Thread suspend, resume, and stop
ThreadGroup
BlockingQueue
Semaphore
ReentrantLock
Executor
ScheduledThreadPoolExecutor