synchronized 与 static synchronized 的区别

目录

首先synchronized 锁的一定是某个对象, 本节讨论的是下面两个情况

public class SyncType{
    public synchronized void syncCurrent()  {

    }

    public synchronized static void syncStatic() { 

    }
}

本节要搞清楚的两个疑问:

  1. syncCurrent 锁定的是什么?
  2. syncStatic 锁定的是什么?

通过接下来的5个例子来解决上面两个问题

为了避免歧义,下文中: 加在方法体的synchronized 叫做普通锁,加在方法体的 static synchronized 叫做静态锁


首先定义一个通用模型,给接下来的五个例子使用

public class SyncType {
    private static final Logger logger = LoggerFactory.getLogger(SyncType.class);

    public synchronized static void syncStaticA() {
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        logger.info("syncStaticA");
    }

    public synchronized static void syncStaticB() {
        logger.info("syncStaticB");
    }

    public synchronized static void syncStaticClass() {
        synchronized (SyncType.class) {
            logger.info("syncStaticClass");
        }
    }

    public synchronized void syncCurrentA() {
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        logger.info("syncCurrentA");
    }

    public synchronized void syncCurrentB() {
        logger.info("syncCurrentB");
    }

    public void syncCurrentC() {
        synchronized (this) {
            logger.info("syncCurrentC");
        }
    }
}

静态锁

 @Test
    public void testStaticSyncA() throws InterruptedException {
        Thread threadA = new Thread(new Runnable() {
            @Override
            public void run() {
                    SyncType.syncStaticA();
            }
        });

        Thread threadB = new Thread(new Runnable() {
            @Override
            public void run() {
                SyncType.syncStaticB();
            }
        });

        threadA.start();
        Thread.sleep(200);
        threadB.start();

        Thread.sleep(3000);
    }

首先开启两个线程,一个运行 静态锁A,一个运行静态锁B.

然后等待200毫秒,让A先启动.

A启动后,等待500毫秒输出 syncStaticA

B启动后,等待A执行完,输出 syncStaticB

静态锁+Class对象锁

@Test
    public void testStaticSyncB() throws InterruptedException {
        Thread threadA = new Thread(new Runnable() {
            @Override
            public void run() {
                    SyncType.syncStaticA();
            }
        });

        Thread threadB = new Thread(new Runnable() {
            @Override
            public void run() {
                SyncType.syncStaticClass();
            }
        });

        threadA.start();
        Thread.sleep(200);
        threadB.start();

        Thread.sleep(3000);
    }

首先开启两个线程,一个运行 静态锁A,一个运行静态B, 锁住SyncType.class对象.

然后等待200毫秒,让A先启动.

A启动后,等待500毫秒输出 syncStaticA

B启动后,等待A执行完,输出 syncStaticClass

普通锁

    @Test
    public void testCurrentSyncA() throws InterruptedException {
        SyncType syncType = new SyncType();
        Thread threadA = new Thread(new Runnable() {
            @Override
            public void run() {
                syncType.syncCurrentA();
            }
        });

        Thread threadB = new Thread(new Runnable() {
            @Override
            public void run() {
                syncType.syncCurrentB();
            }
        });

        threadA.start();
        Thread.sleep(200);
        threadB.start();

        Thread.sleep(3000);
    }

首先开启两个线程,一个运行普通锁A,一个运行普通锁B.

然后等待200毫秒,让A先启动.

A启动后,等待500毫秒输出 syncCurrentA

B启动后,等待A执行完,输出 syncCurrentB

普通锁+this对象锁

    @Test
    public void testCurrentSyncB() throws InterruptedException {
        SyncType syncType = new SyncType();
        Thread threadA = new Thread(new Runnable() {
            @Override
            public void run() {
                syncType.syncCurrentA();
            }
        });

        Thread threadB = new Thread(new Runnable() {
            @Override
            public void run() {
                syncType.syncCurrentC();
            }
        });

        threadA.start();
        Thread.sleep(200);
        threadB.start();

        Thread.sleep(3000);
    }

首先开启两个线程,一个运行普通锁A,一个运行普通锁B.

然后等待200毫秒,让threadA先启动.

threadA启动后,等待500毫秒输出 syncCurrentA

threadB启动后,等待A执行完,输出 syncCurrentC

静态锁+普通锁

    @Test
    public void testCurrentAndStaticSync() throws InterruptedException {
        SyncType syncType = new SyncType();
        Thread threadA = new Thread(new Runnable() {
            @Override
            public void run() {
                syncType.syncCurrentA();
            }
        });

        Thread threadB = new Thread(new Runnable() {
            @Override
            public void run() {
                SyncType.syncStaticA();

            }
        });

        threadA.start();
        Thread.sleep(200);
        threadB.start();

        Thread.sleep(3000);
    }

首先开启两个线程,一个运行普通锁A,一个运行静态锁A.

然后等待200毫秒,让threadA先启动.

threadA启动后,等待500毫秒输出 syncCurrentA

threadB启动后,不等待threadA, 输出 syncStaticA

总结

通过以上5个例子说明;
1. synchronized 锁的是this对象
2. static synchronized 锁的是 当前类的Class对象

猜你喜欢

转载自blog.csdn.net/mz4138/article/details/80924296