Java Thread synchronized keyword for synchronization

Introduction

Without the synchronized keyword, while a thread is sleeping after reading the value of the account's balance, another method will read the account's balance.

So both the methods will modify the same balance and one of the operations won't be reflected in the final result.

Using the synchronized keyword, we can have work on shared data in concurrent applications.

Without synchronized keyword

public class Main {
  public static void main(String[] args) {
    Account account = new Account();
    account.setBalance(1000);//w w  w. ja v  a 2  s .com

    SaveThread company = new SaveThread(account);
    Thread companyThread = new Thread(company);

    ConsumeThread bank = new ConsumeThread(account);
    Thread bankThread = new Thread(bank);

    System.out.printf("Account : Initial Balance: %f\n", account.getBalance());

    companyThread.start();
    bankThread.start();

    try {
      // Wait for the finalization of the Threads
      companyThread.join();
      bankThread.join();
      // Print the final balance
      System.out.printf("Account : Final Balance: %f\n", account.getBalance());
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
  }
}

class Account {
  private double balance;

  public double getBalance() {
    return balance;
  }

  public void setBalance(double balance) {
    this.balance = balance;
  }

  public void addAmount(double amount) {
    double tmp = balance;
    try {
      Thread.sleep(10);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
    tmp += amount;
    balance = tmp;
  }

  public void subtractAmount(double amount) {
    double tmp = balance;
    try {
      Thread.sleep(10);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
    tmp -= amount;
    balance = tmp;
  }
}

class ConsumeThread implements Runnable {

  private Account account;

  public ConsumeThread(Account account) {
    this.account = account;
  }

  public void run() {
    for (int i = 0; i < 100; i++) {
      account.subtractAmount(1000);
    }
  }
}

class SaveThread implements Runnable {

  private Account account;

  public SaveThread(Account account) {
    this.account = account;
  }

  public void run() {
    for (int i = 0; i < 100; i++) {
      account.addAmount(1000);
    }
  }
}

Using synchronized keyword

public class Main {
  public static void main(String[] args) {
    Account account = new Account();
    account.setBalance(1000);//ww w . j av  a  2  s .c o m

    SaveThread company = new SaveThread(account);
    Thread companyThread = new Thread(company);

    ConsumeThread bank = new ConsumeThread(account);
    Thread bankThread = new Thread(bank);

    System.out.printf("Account : Initial Balance: %f\n", account.getBalance());

    companyThread.start();
    bankThread.start();

    try {
      // Wait for the finalization of the Threads
      companyThread.join();
      bankThread.join();
      // Print the final balance
      System.out.printf("Account : Final Balance: %f\n", account.getBalance());
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
  }
}

class Account {
  private double balance;

  public double getBalance() {
    return balance;
  }

  public void setBalance(double balance) {
    this.balance = balance;
  }

  public synchronized void addAmount(double amount) {
    double tmp = balance;
    try {
      Thread.sleep(10);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
    tmp += amount;
    balance = tmp;
  }

  public synchronized void subtractAmount(double amount) {
    double tmp = balance;
    try {
      Thread.sleep(10);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
    tmp -= amount;
    balance = tmp;
  }
}

class ConsumeThread implements Runnable {

  private Account account;

  public ConsumeThread(Account account) {
    this.account = account;
  }

  public void run() {
    for (int i = 0; i < 100; i++) {
      account.subtractAmount(1000);
    }
  }
}

class SaveThread implements Runnable {

  private Account account;

  public SaveThread(Account account) {
    this.account = account;
  }

  public void run() {
    for (int i = 0; i < 100; i++) {
      account.addAmount(1000);
    }
  }
}



PreviousNext

Related