Java多线程

synchronized

用法

synchronized可以用来锁方法锁代码块

锁方法又可以分成对象锁和类锁,synchronized加在普通方法上就是锁得是当前对象;加在static 的方法上锁的是当前类。

锁代码块也可以分成对象锁和类锁,在方法中使用synchronized(object)手动指定锁的对象;synchronized(object.class)锁的是类。类锁跟对象没关系。

总体来说,synchronized锁的对象和类。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class SynTest{
Object obj = new Object();

// 同在方法上
// 对象锁,锁new出的对象
public synchronized void lock1(){}

// 用在方法上
// 类锁,锁new出的类
public synchronized static void lock2(){}

// 锁代码块
// 对象锁
public void lock3(){
synchronized(object){
//todo
}
}
// 类锁
public void lock4(){
stnchronized(SynTest.class){
//todo
}
}
}

注:在普通方法上加锁,锁得是对象,哪个对象调用得这个加锁方法,锁的就是哪个对象。普通同步方法只能用在单例上,因为单例共用一个对象,多例中会有多个对象了,就是多把锁了。

特性

synchronized锁定一段代码或方法的时候,代表同一时刻最多只有一条线程执行这段代码,所以并发的原子性、可见性、有序性它都可以保证。

可重入性:synchronized是可以重入锁,同一个线程拿到锁后再遇到该锁,还可以获取该锁。它底层是通过一个计数器来实现的,获取该锁,计数器+1,在获取该锁,计数器再+1。释放锁,计数器-1,直到计数器为0,其他线程才可以竞争该锁。可重入性的好处是避免死锁。

不可被中断,不能响应超时:线程进入了锁里,其他线程只能在外面阻塞,没办法中断这个线程,如果这个线程发生死锁了,其他线程永远阻塞,可能导致程序崩溃。可以用ReentrantLock替换,它是可以被中断的。

当synchronized正常退出或抛出异常时会主动释放锁。

参考链接:(57条消息) synchronized_csdn_binger的博客-CSDN博客

作者

bd160jbgm

发布于

2021-09-04

更新于

2021-09-04

许可协议