synchronized 是 Java 原生隐式锁,兼具原子性、可见性与有序性。作为并发编程基础工具,其无需手动管理锁生命周期,为多线程共享资源安全访问提供简洁可靠的同步保障。
1.synchronized的写法
- 写法一:
Java
synchronized (/*对象名*/){ // 进这个{ 程序就自动上锁了
// 执行的逻辑内容
}// 程序走到这,就会自动解锁
- 写法二:
Java
synchronized public static void add() { // 修饰方法名
count++;
}
2. synchronized的特性
- 互斥
这个是synchronized的基本特性,多个线程遇到synchronized的时候,如果是同一个对象上的锁的话,那么就会阻塞等待前一个线程结束。
Java
Object locker = new Object();
Thread t1 = new Thread(()->{
synchronized (locker){
for (int i = 0; i < 50000; i++) {
count++;
}
}
});
Thread t2 = new Thread(()->{
synchronized (locker){
for (int i = 0; i < 50000; i++) {
count++;
}
}
});
- 可重入
synchronized同步块对同一条线程来说是可以重入的,不会出现自己锁自己的情况
Java
synchronized (locker){
synchronized (locker){
for (int i = 0; i < 50000; i++) {
count++;
}
}
}
注: 正常来说这个代码的执行是这样的,外面那个synchronized把线程锁住了,这种情况叫做死锁,随后里面那个synchronized被阻塞等待了,但是大佬们早就想到这个了,所以在Java中就给synchronized整了个可重入的特性,这里只是针对了一个线程一把锁,有可重入锁来解决这个。
但是真正上锁和解锁都是最外围的那个synchronized来进行的
3. 如何自己手搓一个可重入锁
- 在所内部记录当前是哪个对象持有这个锁,后续加锁时,都进行判断,是否是同一个对象锁持有的锁。
- 通过计数器来,判断哪个才是真正解锁的}。