当它锁定一个方法或者一个代码块的时候,同一时刻最多只有一个线程执行这段代码。当两个并发线程访问同一个对象object中的这个加锁同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。
那问题来了,如果两个线程访问的是这个对象的不同实例,还会阻塞吗?
当它锁定一个方法或者一个代码块的时候,同一时刻最多只有一个线程执行这段代码。当两个并发线程访问同一个对象object中的这个加锁同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。
那问题来了,如果两个线程访问的是这个对象的不同实例,还会阻塞吗?
请看下面这个代码:
public static class X {
private static final Object staticObj = new Object();
// 不同的线程访问不同的这个类的实例是不会相互阻塞的,因为lock的对象不同
public void lockOnInstance() {
synchronized (this) {
}
}
// 不同的线程访问不同的这个类的实例是不会相互阻塞的,因为lock的对象不同
public synchronized void lockOnInstance2() {
}
// 不同的线程访问不同的这个类的实例是相互阻塞的,因为lock的对象是同一个
public void lockOnStatic() {
synchronized (staticObj) {
}
}
// 不同的线程访问不同的这个类的实例是相互阻塞的,因为lock的对象是同一个
public synchronized static void lockOnStatic2() {
}
}
synchronized的用法有以下三种
指定对象加锁。类似于synchronized (instance) {}。
直接作用于实例方法。相当于对当前实例加锁,进入同步方法前要获得当前实例的锁。
直接作用于静态方法。相当于对当前类加锁,进入同步方法前获得当前类的锁。
对于上面的1、2.必须是同一对象或者同一实例时才会使线程阻塞。
8 回答6.6k 阅读
4 回答717 阅读✓ 已解决
2 回答3.4k 阅读
3 回答1.9k 阅读✓ 已解决
1 回答2.2k 阅读✓ 已解决
1 回答2.1k 阅读✓ 已解决
1 回答974 阅读✓ 已解决
那问题来了,如果两个线程访问的是这个对象的不同实例,还会阻塞吗?
答案是不会阻塞,也就是必须是同一个对象,synchronized方法或者synchronized(this)才会阻塞。
不过如果是synchronized static方法,或者synchronized(this.class)这样的写法,就相当于全局锁,对象实例无关。
说白了,synchronized(obj)锁住的是括号中的对象,如果不是同一个对象则不会阻塞。
可以参考
http://xxgblog.com/2012/11/15...
http://xxgblog.com/2013/05/16...