码迷,mamicode.com
首页 > 编程语言 > 详细

Java Synchronized Blocks

时间:2015-07-17 13:54:57      阅读:167      评论:0      收藏:0      [点我收藏+]

标签:

From http://tutorials.jenkov.com/java-concurrency/synchronized.html

By Jakob Jenkov

Table of Contents

A Java synchronized block marks a method or a block of code as synchronized. Java synchronized    blocks can be used to avoid race conditions.

The Java synchronized Keyword

    Synchronized blocks in Java are marked with the synchronized keyword.    A synchronized block in Java is synchronized on some object.    All synchronized blocks synchronized on the same object can only have one thread    executing inside them at the same time. All other threads attempting to enter    the synchronized block are blocked until the thread inside the synchronized block    exits the block.

    The synchronized keyword can be used to mark four different types    of blocks:

  1. Instance methods
  2. Static methods
  3. Code blocks inside instance methods
  4. Code blocks inside static methods

    These blocks are synchronized on different objects. Which type of synchronized block    you need depends on the concrete situation.

Synchronized Instance Methods

    Here is a synchronized instance method:

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

    Notice the use of the synchronized keyword in the method declaration.    This tells Java that the method is synchronized.

    A synchronized instance method in Java is synchronized on the instance (object)    owning the method. Thus, each instance has its synchronized methods synchronized    on a different object: the owning instance. Only one thread can execute inside a    synchronized instance method. If more than one instance exist, then one thread    at a time can execute inside a synchronized instance method per instance.    One thread per instance.

Synchronized Static Methods

    Static methods are marked as synchronized just like instance methods using the     synchronized keyword. Here is a Java synchronized static method    example:

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

    Also here the synchronized keyword tells Java that the method    is synchronized.

    Synchronized static methods are synchronized on the class object of    the class the synchronized static method belongs to. Since only one    class object exists in the Java VM per class, only one thread can    execute inside a static synchronized method in the same class.

    If the static synchronized methods are located in different classes,    then one thread can execute inside the static synchronized methods    of each class. One thread per class regardless of which static synchronized method    it calls.

Synchronized Blocks in Instance Methods

    You do not have to synchronize a whole method. Sometimes it is preferable to synchronize    only part of a method. Java synchronized blocks inside methods makes this possible.

    Here is a synchronized block of Java code inside an unsynchronized Java method:

  public void add(int value){

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

    This example uses the Java synchronized block construct to mark a block of    code as synchronized. This code will now execute as if it was a synchronized    method.

    Notice how the Java synchronized block construct takes an object in parentheses. In the example    "this" is used, which is the instance the add method is called on. The object taken    in the parentheses by the synchronized construct is called a monitor object. The code    is said to be synchronized on the monitor object. A synchronized instance method uses the object    it belongs to as monitor object.

    Only one thread can execute inside a Java 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);
       }
    }
  }

    Thus only a single thread can execute inside either of the two synchronized blocks in this example.

    Had the second synchronized block been synchronized on a different object than this,    then one thread at a time had been able to execute inside each method.

Synchronized Blocks in Static Methods

    Here are the same two examples as static methods. These methods are synchronized on the class object    of 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);  
       }
    }
  }

    Only one thread can execute inside any of these two methods at the same time.

    Had the second synchronized block been synchronized on a different object    than MyClass.class, then one thread could execute inside    each method at the same time.

Java Synchronized Example

    Here is an example that starts 2 threads and have both of them call the add    method on the same instance of Counter. Only one thread at a time will be able to call    the add method on the same instance, because the method is synchronized on    the 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 are created. The same Counter instance is passed    to both of them in their constructor.    The Counter.add() method is synchronized on the    instance, because the add method is an instance method, and marked    as synchronized. Therefore only one of the threads can call the    add() method at a time. The other thread will wait until the first thread    leaves 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    simultaneously. 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 reference    the same counter instance. The add method of     counterA and counterB are synchronized    on their two owning instances. Calling add() on     counterA will thus not block a call to add()    on counterB.

Java Concurrency Utilities

    The synchronized mechanism was Java‘s first mechanism for synchronizing access to    objects shared by multiple threads. The synchronized mechanism isn‘t very advanced though.    That is why Java 5 got a whole set of concurrency utility classes    to help developers implement more fine grained concurrency control than what you get with synchronized.

Java Synchronized Blocks

标签:

原文地址:http://www.cnblogs.com/kid551/p/4653903.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!