Java Synchronized Blocks

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.

时间: 2024-11-13 12:03:51

Java Synchronized Blocks的相关文章

Java Synchronized Blocks vs. Methods

It's possible to synchronize both an entire method and a section of code within a method, and you may wonder which one you should use. To understand which is appropriate in a given situation, it’s important to consider what synchronization really pro

Java synchronized 总结

在Java开发的时候经常会用到关键字synchronized来对代码进行同步,在使用的过程中,对于synchronized确不是很熟悉,最近在看Spring源码时,发现有不少地方都用到同步,因此,趁此机会,研究一下. 1. synchronized锁的对象 Java中的每一个对象都可以作为锁. 1)对于同步方法,锁是当前实例对象. 2)对于静态同步方法,锁是当前对象的Class对象.因为在Java 虚拟机中一个类只能对应一个类对象,所以同时只允许一个线程执行同一个类中的静态同步方法. 3)对于同

Java synchronized详解

Java synchronized详解 第一篇: 使用synchronized 在编写一个类时,如果该类中的代码可能运行于多线程环境下,那么就要考虑同步的问题.在Java中内置了语言级的同步原语--synchronized,这也大大简化了Java中多线程同步的使用.我们首先编写一个非常简单的多线程的程序,是模拟银行中的多个线程同时对同一个储蓄账户进行存款.取款操作的. 在程序中我们使用了一个简化版本的Account类,代表了一个银行账户的信息.在主程序中我们首先生成了1000个线程,然后启动它们

java synchronized

synchronized 关键字,它包括两种用法:synchronized 方法和 synchronized 块.  1. synchronized 方法:通过在方法声明中加入 synchronized关键字来声明 synchronized 方法.如:  public synchronized void accessVal(int newVal);  synchronized 方法控制对类成员变量的访问:每个类实例对应一把锁,每个 synchronized 方法都必须获得调用该方法的类实例的锁方

java synchronized使用

java synchronized 基本上,所有并发的模式在解决线程冲突问题的时候,都是采用序列化共享资源的方案.这意味着在给定时刻只允许一个任务访问该资源.这个一般通过在代码上加一条锁语句实现,因为锁语句产生一种互斥排斥的效果,这种机制常常被称为互斥机制. 线程是簇拥在共享资源门前,并不是排队进入,可以通过yield()和setPriority()来给线程调度提供建议,但这些建议未必会有多大的效果.这取决与你的具体平台和vm的实现:)--//from <think in java> java

java synchronized wait

在多个线程要互斥访问数据,但线程间需要同步时——例如任务分多个阶段,特定线程负责特定阶段的情况,经常合作使用synchronized 和 wait() /** * * 计算输出其他线程锁计算的数据 * @author * */ public class Main { public static void main(String[] args) { ThreadB b = new ThreadB(); b.start();// 启动计算线程 synchronized (b) { try { Sys

Java Synchronized 与 ThreadLocal 异同

同:都是为了线程安全 异:synchronized是利用锁的机制,使变量或代码块在某一时该只能被一个线程访问.而ThreadLocal为每一个线程都提供了变量的副本,使得每个线程在某一时间访问到的并不是同一个对象, 这样就隔离了多个线程对数据的数据共享.而Synchronized却正好相反,它用于在多个线程间通信时能够获得数据共享.Synchronized用于线程间的数据共享,而ThreadLocal则用于线程间的 数据隔离.当然ThreadLocal并不能替代synchronized,它们处理

java synchronized(一)

java synchronized主要用于控制线程同步,中间有很多小的细节,知识,这里我简单的整理一下,做个记录.主要用于方法和代码块的控制 先说说方法控制 模拟银行存款和取款,创建一个Account类,两个属性,一个name和accout.先存1w进去,在用一100个线程取钱1k和存1k.等待所有线程结束后,输出account.没有synchronized控制会造成account不等于1w.使用了synchronized结果正确,性能降低了很多.下面贴一下代码 参考:http://www.cn

Java Synchronized 关键字

本文内容 Synchronized 关键字 示例 Synchronized 方法 内部锁(Intrinsic Locks)和 Synchronization 参考资料 下载 Demo Synchronized 关键字 Java 语言提供两个基本的同步机制:synchronized 方法(synchronized methods )和 synchronized  语句(synchronized statements). 示例 先大概说一下 Java Synchronized 关键字,当它用来修饰一