静态synchronized方法的锁是Java文件对应的Class对象,而非静态synchronized方法的锁是是个实例对象,这两个锁并不是同一个,因此静态synchronized方法和非静态synchronized方法之间不会相互干扰
验证
public class Service {
synchronized public static void printA() { //Class锁
try {
System.out.println("线程"+Thread.currentThread().getName()+"进入printA");
Thread.sleep(2000);
System.out.println("线程" +Thread.currentThread().getName()+"离开printA");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
synchronized public static void printB() { //Class锁
try {
System.out.println("线程"+Thread.currentThread().getName()+"进入printB");
Thread.sleep(2000);
System.out.println("线程" +Thread.currentThread().getName()+"离开printB");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
synchronized public void printC() { //对象锁
try {
System.out.println("线程"+Thread.currentThread().getName()+"进入printC");
Thread.sleep(2000);
System.out.println("线程" +Thread.currentThread().getName()+"离开printC");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class ThreadA extends Thread{
public void run() {
Service.printA();
}
}
public class ThreadB extends Thread{
public void run() {
Service.printB();
}
}
public class ThreadC extends Thread{
private Service service;
public ThreadC(Service service) {
this.service = service;
}
public void run() {
service.printC();
}
}
public static void main(String[] args) {
Service service = new Service();
ThreadA threadA = new ThreadA();
threadA.setName("A");
threadA.start();
ThreadB threadB = new ThreadB();
threadB.setName("B");
threadB.start();
ThreadC threadC = new ThreadC(service);
threadC.setName("C");
threadC.start();
}
线程threadA和线程threadB是竞争同一个Class锁,threadC是实例锁,运行的结果是
线程A进入printA
线程C进入printC
线程A离开printA
线程C离开printC
线程B进入printB
线程B离开printB
可以看出,并不是同一个锁,即使线程threadA和线程threadB的run方法是通过实例调用的静态synchronized方法,锁仍然是Class对象,而不是实例
public class ThreadA extends Thread{
private Service service;
public ThreadA(Service service) {
this.service = service;
}
public void run() {
try {
Thread.sleep(2000);
service.printA();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
这次threadA是通过service的实例调用静态synchronized方法,和threadC也不会产生竞争,结果是和上面的一样的