同步方法中加static与不加static的区别
无static时
在不加static时候 ,synchronized默认的锁对象为 this,也就是调用该方法的那个对象,对于同一个对象调用的不同的同步方法,无论如何休眠,先执行结束的都是 先拿到锁的那个线程
```java
public class Test_1{
public static void main(String[] args) throws InterruptedException {
A a=new A();
new Thread(()->{a.a();},"A").start();
TimeUnit.SECONDS.sleep(1);
new Thread(()->{a.b();},"B").start();
//虽然a方法休眠了4s 但是调用对象就只有一个a对象,线程A先拿到的锁,所以A线程先执行完, B线程再执行。
}
}
class A{
public synchronized void a(){
//在方法上加synchronized 等价于方法里的同步代码块synchronized(this){xxx}
try {
TimeUnit.SECONDS.sleep(4);
System.out.println("a");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
}
}
public synchronized void b(){
System.out.println("b");
}
}
有static 时 类锁
因为 static 是在类加载的时候就加载 (可以理解为:类初始化的时候,synchronized锁也跟着一起初始化了,所以无论创建多少个对象,只有一个synchronized锁被初始化),所以 被static修饰的同步 方法就是那个类本身,也就是类锁 ,类 只有一个,无论我们创建几个对象去调用这个同步方法,都是先拿到类锁的那一个线程先执行
```java
public class Test_1{
public static void main(String[] args) throws InterruptedException {
A a=new A();
A b=new A();
new Thread(()->{a.a();},"A").start();
TimeUnit.SECONDS.sleep(1);
new Thread(()->{b.b();},"B").start();
// 结果为 线程A先执行完,再是线程B,因为这里的锁
//是类锁,被线程A的 a对象获取了 ,所以B线程的b对象 要等待
}
}
class A{
public static synchronized void a(){
try {
TimeUnit.SECONDS.sleep(4);
System.out.println("a");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static synchronized void b(){
System.out.println("b");
}
}