Java Synchronized Blocks
From http://tutorials.jenkov.com/java-concurrency/synchronized.html
By Jakob Jenkov
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:
- Instance methods
- Static methods
- Code blocks inside instance methods
- 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的更多相关文章
- Java Synchronized Blocks vs. Methods
It's possible to synchronize both an entire method and a section of code within a method, and you ma ...
- java synchronized(一)
java synchronized主要用于控制线程同步,中间有很多小的细节,知识,这里我简单的整理一下,做个记录.主要用于方法和代码块的控制 先说说方法控制 模拟银行存款和取款,创建一个Account ...
- java synchronized使用
java synchronized 基本上,所有并发的模式在解决线程冲突问题的时候,都是采用序列化共享资源的方案.这意味着在给定时刻只允许一个任务访问该资源.这个一般通过在代码上加一条锁语句实现,因为 ...
- Java synchronized 详解
Java synchronized 详解 Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码. 1.当两个并发线程访问同一个对象object ...
- Java Synchronized 关键字
本文内容 Synchronized 关键字 示例 Synchronized 方法 内部锁(Intrinsic Locks)和 Synchronization 参考资料 下载 Demo Synchron ...
- Java synchronized 关键字详解
Java synchronized 关键字详解 前置技能点 进程和线程的概念 线程创建方式 线程的状态状态转换 线程安全的概念 synchronized 关键字的几种用法 修饰非静态成员方法 sync ...
- Java synchronized对象级别与类级别的同步锁
Java synchronized 关键字 可以将一个代码块或一个方法标记为同步代码块.同步代码块是指同一时间只能有一个线程执行的代码,并且执行该代码的线程持有同步锁.synchronized关键字可 ...
- Java 同步代码块 - Synchronized Blocks
java锁实现原理: http://blog.csdn.net/endlu/article/details/51249156 The synchronized keyword can be used ...
- Java Synchronized的原理
我们先通过反编译下面的代码来看看Synchronized是如何实现对代码块进行同步的: public class SynchronizedDemo{ public void method(){ syn ...
随机推荐
- ASP.NET MVC 部署全站HTTPS
什么是全站HTTPS 全站HTTPS就是指整个网站的所有页面,所有资源全部使用HTTPS链接. 当用户的某个请求是明文的HTTP时,应该通过HTTP状态码301永久重定向到对应的HTTPS链接. 为了 ...
- oracle中用户删除不了,ORA-01940提示 “无法删除当前已连接用户”
Oracle删除用户的提示无法删除当前已连接用户两种解决方法如下: 1.先锁定用户.然后查询进程号,最后删除对应的进程.在删除对应的用户 SQL>alter user XXX account l ...
- Tomcat实现分析(一)--类加载及容器组件
启动脚本 启动命令中的参数如下: org.apache.catalina.startup.Bootstrap start -Djava.util.logging.config.file=/opt/ap ...
- 黑马程序员-循环引用问题和weak
使用weak reference(弱引用)来避免retain cycle 对一个对象发送retain消息会创建对这个对象的强引用(strong reference).如果两个对象都有一个强引用指向对方 ...
- WPF 自定义TextBox,可控制键盘输入内容
非原创,整理之前的代码的时候找出来的,可用,与大家分享一下! public class NumbericBoxWithZero : NumericBox { public NumbericBoxWit ...
- HDU 1284 钱币兑换问题
动态转移方程:dp[i] = dp[i - 1] + dp[i - 2] + dp[i - 3] 即要想兑够 i,有三种方法: 1.从 i - 1 再增加一个1分的: 2.从 i - 2 再增加一个2 ...
- java-代理模式及动态代理
代理模式 代理模式的作用是:为其他对象提供一种代理以控制对这个对象的访问.在考虑到性能或安全等因素的情况下,一个客户不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用. ...
- Python 之 lamda 函数
1.例子 语法:lambda [args1,argus2....]:expression map(lambda x: x*x, [y for y in range(10)]) lambda:" ...
- IOS9 新加关键字 nullable、nonnull、null_unspecified、null_resettable
#import "ViewController.h" @interface ViewController () @property(nonatomic,nullable)NSStr ...
- 管理我的数据之GDBM
管理我的数据之GDBM 作者 He YiJun – storysnail<at>gmail.com 团队 ls 版权 转载请保留本声明! 本文档包含的原创代码根据General Publi ...