Java多线程
synchronized
用法
synchronized可以用来锁方法和锁代码块。
锁方法又可以分成对象锁和类锁,synchronized加在普通方法上就是锁得是当前对象;加在static 的方法上锁的是当前类。
锁代码块也可以分成对象锁和类锁,在方法中使用synchronized(object)手动指定锁的对象;synchronized(object.class)锁的是类。类锁跟对象没关系。
总体来说,synchronized锁的对象和类。
1 | public class SynTest{ |
注:在普通方法上加锁,锁得是对象,哪个对象调用得这个加锁方法,锁的就是哪个对象。普通同步方法只能用在单例上,因为单例共用一个对象,多例中会有多个对象了,就是多把锁了。
特性
synchronized锁定一段代码或方法的时候,代表同一时刻最多只有一条线程执行这段代码,所以并发的原子性、可见性、有序性它都可以保证。
可重入性:synchronized是可以重入锁,同一个线程拿到锁后再遇到该锁,还可以获取该锁。它底层是通过一个计数器来实现的,获取该锁,计数器+1,在获取该锁,计数器再+1。释放锁,计数器-1,直到计数器为0,其他线程才可以竞争该锁。可重入性的好处是避免死锁。
不可被中断,不能响应超时:线程进入了锁里,其他线程只能在外面阻塞,没办法中断这个线程,如果这个线程发生死锁了,其他线程永远阻塞,可能导致程序崩溃。可以用ReentrantLock替换,它是可以被中断的。
当synchronized正常退出或抛出异常时会主动释放锁。