使用Synchronized (this) 对当前对象进行同步化,这很容易理解;
但对其他对象同步化,应该怎样理解?比如下面的代码,synchronized(syncObject) 语句,syncObject 就是一个普通对象Object,这样又有什么意义了?
import static net.mindview.util.Print.*;
class DualSynch {
private Object syncObject = new Object();
public synchronized void f() {
for(int i = 0; i < 5; i++) {
print("f()");
Thread.yield();
}
}
public void g() {
synchronized(syncObject) {
for(int i = 0; i < 5; i++) {
print("g()");
Thread.yield();
}
}
}
}
public class SyncObject {
public static void main(String[] args) {
final DualSynch ds = new DualSynch();
new Thread() {
public void run() {
ds.f();
}
}.start();
ds.g();
}
}
每个对象都有一个对象锁,
syncdhronized(syncObject)
利用syncObject的对象锁,public synchronized void f()
利用ds的对象锁这段代码里面用到了两个锁,方法f执行的时候需要获取ds对象的锁,方法g执行的时候需要获取syncObject的对象锁。这两个锁没什么关联。
我的理解是 Java 中每个对象都有一把锁,
synchronized (this)
锁的是对象本身,synchronized (object)
锁的是一个作为锁的 Object。以下代码中的两个
synchronized
块之间不构成同步,因为两个块的锁加在了不同对象上利用一个单独的对象作为锁对象。这种情况下也可以使用
ReentrantLock
,然后用它的lock()
、unlock()
代替synchronized
。public synchronized void f()
相当于synchronized (this)
也就是对象本身,synchronized(syncObject)
加锁的是另外一个对象syncObject。这样的结果就是:你new出来一个
DualSynch
对象,在两个线程中f()
方法和g()
方法是可以并发执行的,但是在两个线程中f()
和f()
不能并发执行,g()
和g()
不能并发执行。public synchronized void f()
获得的是对象锁,相对于synchronized(this)
,synchronized(syncObject)
获得的是Object syncObject
的对象锁。当一个线程访问对象中
f()
时,就获得了这个object的对象锁,其它线程对该对象所有同步代码部分的访问都被暂时阻塞。但是,另一个线程仍然可以访问该object中的非synchronized(this)
同步代码块,包括Object syncObject
;同理,一个线程访问对象中g()
时,其它线程对该对象g()
的访问都被暂时阻塞,但仍然可以访问相当于synchronized(this)
的f()
。