引言
在java单线程中,并不会出现资源抢夺的现象,但是在多线程并发中,会出现资源抢夺现象。为了避免这种情况需要上锁
分类
可重入锁,又名递归锁
指的是同一线程外层函数获得锁之后,内层递归函数仍然能获取该锁的代码,在同一个线程在外层方法获取锁的时候,在进入内层方法会自动获取锁,也即是说,线程可以进入任何一个它已经拥有的锁所同步着的代码块。
使用synchronized
1 |
|
结果
1 | t1 invoked sendSMS() //t1线程在外层方法获取锁的时候 |
使用ReentrantLock
1 | import java.util.concurrent.TimeUnit; |
结果
1 |
|
自旋锁
CAS循环比较并交换
是指尝试获取锁的线程不会立即阻塞,而是采用循环的方式去尝试获取锁,这样的好处是减少线程上下文切换的消耗,缺点是循环会消耗CPU
1 | import java.util.concurrent.TimeUnit; |
结果
1 | AA come in... |
读写锁
读时共享资源数据,写时独占资源数据
多个线程同时读一个资源类没有任何问题,所以为了满足并发量,读取共享资源应该可以同时进行,但是如果有一个线程想去写共享资源,就不应该再有其它线程可以对该资源进行读或写。
读-读能共存
读-写不能共存
写-写不能共存
没有使用读写锁前
1 | import java.util.HashMap; |
结果
写时并不满足原子性和独占性,整个过程必须是一个完整的统一体,中间不允许被分割,被打断
1 | 5 正在写入:5 |
使用读写锁后
使用ReentrantReadWriteLock
1 | import java.util.HashMap; |
结果
1 | 4 正在写入:4 |