Synchronized Code Blocks

In Java you can mark a method or a block of code as synchronized. Synchronizedblocks can be used to avoid race conditions.

Here is a synchronized method:

  public synchronized void add(int value){
      this.count += value;
  }

And here is a synchronized block of code inside an unsynchronized add method:

  public void add(int value){

    synchronized(this){
       this.count += value;   
    }
  }

Notice how the synchronized construct takes an object in parantheses. In the example"this" is used, which is the instance the add method is called on. The object takenin the parantheses by the synchronized construct is called a monitor object. The codeis said to be synchronized on the monitor object. A synchronized method uses the object it belongs to as monitor object. A static method uses the class object of the class the method belongs.

Only one thread can execute inside a code block synchronized on the same monitor object.

The following two examples are both synchronized on the instance they are called on.They are therefore equivalent with respect to synchronization:

 
  public class MyClass {
  
    public synchronized void log1(String msg1, String msg2){
       log.writeln(msg1);
       log.writeln(msg2);
    }

  
    public void log2(String msg1, String msg2){
       synchronized(this){
          log.writeln(msg1);
          log.writeln(msg2);
       }
    }
  }

Here are the same two examples as static methods, synchronized on the class objectof the class the methods belong to:

  public class MyClass {

    public static synchronized void log1(String msg1, String msg2){
       log.writeln(msg1);
       log.writeln(msg2);
    }

  
    public static void log2(String msg1, String msg2){
       synchronized(MyClass.class){
          log.writeln(msg1);
          log.writeln(msg2);  
       }
    }
  }

Here is an example that starts 2 threads and have both of them call the addmethod on the same instance of Counter. Only one thread at a time will be able to callthe add method on the same instance, because the method is synchronized onthe instance it belongs to.

  public class Counter{
     
     long count = 0;
    
     public synchronized void add(long value){
       this.count += value;
     }
  }
  public class CounterThread extends Thread{

     protected Counter counter = null;

     public CounterThread(Counter counter){
        this.counter = counter;
     }

     public void run() {
	for(int i=0; i<10; i++){
           counter.add(i);
        }
     }
  }
  public class Example {

    public static void main(String[] args){
      Counter counter = new Counter();
      Thread  threadA = new CounterThread(counter);
      Thread  threadB = new CounterThread(counter);

      threadA.start();
      threadB.start(); 
    }
  }

Two threads thread are created. The same Counter instance is passedto both of them in their constructor. The Counter.add() method is synchronized on theinstance, because the add method is an instance method, and markedas synchronized. Therefore only one of the threads can call theadd() method at a time. The other thread will wait until the first threadleaves the add() method, before it can execute the method itself.

If the two threads had referenced two separate Counter instances,there would have been no problems calling the add() methods simultanously. The calls would have been to different objects, so the methods called would also be synchronized on different objects(the object owning the method). Therefore the calls would not block.Here is how that could look:

  public class Example {

    public static void main(String[] args){
      Counter counterA = new Counter();
      Counter counterB = new Counter();
      Thread  threadA = new CounterThread(counterA);
      Thread  threadB = new CounterThread(counterB);

      threadA.start();
      threadB.start(); 
    }
  }
Notice how the two threads, threadA and threadB, no longer referencethe same counter instance
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值