synchronized
如果在同一个对象上,不同线程调用了不同的synchronized方法,方法的调用也是串行的,
比如线程1先调用对象obj的synchronized的方法A,线程2调用了同一个对象obj的synchronized的方法B。
线程1先执行完方法A,线程2才轮到执行方法B。尽管这两个不是同一个方法。
package com.concurrent.demo;
class Sync{
public synchronized void func1(){
System.out.println("func1 begins");
try {
Thread.sleep(7000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("func1 ends");
}
public synchronized void func2(){
for(int i =0;i<10;i++){
System.out.println("func2");
}
}
}
public class SyncDemo {
public static void main(String[] args) {
Sync obj = new Sync();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
obj.func1();
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
obj.func2();
}
});
t1.start();
t2.start();
}
}
输出
func1 begins
func1 ends
func2
func2
func2
func2
func2
func2
func2
func2
func2
func2
如果去掉func2的synchronized关键字,那么func2就不用等待func1执行完了。
问题1:对于非静态方法,synchronized针对的是同一个对象吗?
是的。每一个对象有一个内部锁, 并且该锁有一个内部条件。 由锁来管理那些试图进入 synchronized 方法的线程, 由条件来管理那些调用 wait 的线程。
Java 中的每一个对象都有一个内部锁。
每一个java对象有内在锁,intrinsic lock
调用synchronized修饰的方法时,线程必须取得该对象的内在锁。
内部对象锁只有一个相关条件。wait 方法添加一个线程到等待集中, notifyAll /notify 方法解除等待线程的阻塞状态。 换句话说, 调用 wait 或 notityAll 等价于
intrinsicCondition.await();
intrinsicCondition.signal();
问题2:为什么需要Condition?
因为你获取了锁之后,执行时发现某个条件不满足,要等待条件满足了才能往下继续执行,但这个线程获得锁之后其他线程想执行这段代码是无法操作的,这时候需要释放锁。通过条件对象,释放锁并且进入阻塞状态。
网友评论