目录
首先synchronized 锁的一定是某个对象, 本节讨论的是下面两个情况
public class SyncType{
public synchronized void syncCurrent() {
}
public synchronized static void syncStatic() {
}
}
本节要搞清楚的两个疑问:
- syncCurrent 锁定的是什么?
- 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对象