关键字synchronized取得的锁都是对象锁,而不是把一段代码或方法(函数)当作锁,这里如果是把一段代码或方法(函数)当作锁,其实获取的也是对象锁,只是监视器(对象)不同而已,哪个线程先执行带synchronized关键字的方法,哪个线程就持有该方法所属对象的锁,其他线程都只能呈等待状态。但是这有个前提:既然锁叫做对象锁,那么势必和对象相关,所以多个线程访问的必须是同一个对象。
package com.orac.zhang;
public class People {
static int sum=0;
public synchronized void fun() {
for(int i=0;i<200;i++) {
System.out.println("sum:"+sum);
sum++;
}
}
}
创建两个不同的对象
package com.orac.zhang;
public class Test {
public static void main(String[] args) {
People people1=new People();
People people2=new People();
Thread thread1=new Thread() {
@Override
public void run() {
people1.fun();
}
};
Thread thread2=new Thread() {
@Override
public void run() {
people2.fun();
}
};
thread1.start();
thread2.start();
}
}
运行结果发现两个线程没用同步执行,导致运行结果没用从大到小排列
package com.orac.zhang;
public class Test {
public static void main(String[] args) {
People people=new People();
Thread thread1=new Thread() {
@Override
public void run() {
people.fun();
}
};
Thread thread2=new Thread() {
@Override
public void run() {
people.fun();
}
};
thread1.start();
thread2.start();
}
}
只用一个对象调用,运行结果是我们想要的
所以如果多个线程访问的是多个对象,那么Java虚拟机就会创建多个锁,就像上面的例子一样,创建了两个People对象,就产生了2个锁。既然两个线程持有的是不同的锁,自然不会受到"等待释放锁"这一行为的制约。