Java synchronized 与static synchronized

70 阅读2分钟

前言:小编最开始以为只要不是同一个方法就不可以再不同的线程中同时运行(显然是错误的)。

示例1:同一对象在不同线程中执行不同的synchronized方法

@SneakyThrows
public synchronized void syn1()  {
    System.out.println("syn1");
    Thread.sleep(1000);
    System.out.println("syn1 等待1秒后");
}

@SneakyThrows
public  void syn2()  {
    System.out.println("syn2");
    Thread.sleep(1000);
    System.out.println("syn2 等待1秒后");
}

public static void main(String[] args) {
        UserServiceImplTest userServiceImplTest = new UserServiceImplTest();

        new Thread(() -> userServiceImplTest.syn1()).start();
        new Thread(() -> userServiceImplTest.syn2()).start();
}
-- 运行结果
-- syn1 
-- syn1 等待1秒后
  
-- syn2
-- syn2 等待1秒后

结论:明显能看出来两个不同的线程里执行该类中带synchronized的方法是会需要等待对象锁释放后才能继续执行下一个方法的

示例2:不同对象在不同线程中执行同一个的synchronized方法

@SneakyThrows
public synchronized void syn1()  {
    System.out.println("syn1");
    Thread.sleep(1000);
    System.out.println("syn1 等待1秒后");
}

@SneakyThrows
public  void syn2()  {
    System.out.println("syn2");
    Thread.sleep(1000);
    System.out.println("syn2 等待1秒后");
}

public static void main(String[] args) {
        UserServiceImplTest userServiceImplTest = new UserServiceImplTest();
        UserServiceImplTest userServiceImplTest1 = new UserServiceImplTest();
        new Thread(() -> userServiceImplTest.syn1() ).start();
        new Thread(() -> userServiceImplTest1.syn1()).start();
}
-- 运行结果
-- syn1
-- syn1
-- syn1 等待1秒后
-- syn1 等待1秒后syn1 

结论:不同的对象在不同的线程中执行同一个synchronized方法时,不需要等待其他对象锁的释放因为synchronized目前锁的是this不同的对象相互不影响。

示例3:同一对象在不同线程中执行不同的synchronized方法(有一个方法时静态方法 static)

@SneakyThrows
public synchronized static void syn1()  {
    System.out.println("syn1");
    Thread.sleep(1000);
    System.out.println("syn1 等待1秒后");
}

@SneakyThrows
public  void syn2()  {
    System.out.println("syn2");
    Thread.sleep(1000);
    System.out.println("syn2 等待1秒后");
}

public static void main(String[] args) {
        UserServiceImplTest userServiceImplTest = new UserServiceImplTest();

        new Thread(() -> userServiceImplTest.syn1()).start();
        new Thread(() -> userServiceImplTest.syn2()).start();
}
-- 运行结果
-- syn1
-- syn2
-- syn1 等待1秒后
-- syn2 等待1秒后

结论:同一对象在不同的线程中执行的方法如果有一个是静态方法的锁(类锁)跟普通方法的锁(实例锁)是互不干扰的

示例3:不同对象在不同线程中执行同一个的synchronized 静态(static)方法

@SneakyThrows
public synchronized static void syn1()  {
    System.out.println("syn1");
    Thread.sleep(1000);
    System.out.println("syn1 等待1秒后");
}

@SneakyThrows
public void syn2()  {
    System.out.println("syn2");
    Thread.sleep(1000);
    System.out.println("syn2 等待1秒后");
}

public static void main(String[] args) {
        UserServiceImplTest userServiceImplTest = new UserServiceImplTest();
        UserServiceImplTest userServiceImplTest1 = new UserServiceImplTest();
        new Thread(() -> userServiceImplTest.syn1()).start();
        new Thread(() -> userServiceImplTest1.syn1()).start();
}
-- 运行结果
-- syn1
-- syn1 等待1秒后
-- syn1
-- syn1 等待1秒后

结论:不同的对象在不同的线程中执行同一个静态方法时,会触发类锁从而导致需要等待test.syn1方法结束后才会执行test1.syn1方法