有关锁的内容
一、相关概念
1.什么是乐观锁、悲观锁
乐观锁是认为自己在使用数据的时候,没有其它线程会进行更改操作,因此不会添加锁,而是以来版本号或CAS自旋进行数据的校验。
悲观锁是认为自己在使用数据时,总有其它线程进行更改操作,因此一定会添加锁
2.什么是公平锁、非公平锁
公平锁是按照线程申请顺序来获取锁,Lock锁中,new ReentrantLock(true)代表公平锁
非公平锁并不会按照线程申请顺序来获取锁,有可能造成优先级反转和饥饿状态
非公平锁的效率更高,因为公平锁会频繁进行上下文切换,因此效率不如非公平锁
3.可重入锁
可重入锁的概念是锁里可以嵌套另一个锁,我们熟知的synchronized和Lock都是可重入锁
可重入锁内部有一个目标对象计数器,每有一个锁,就会+1,直到成为0,代表锁已被释放
4.中断锁机制
停止
一个线程不应该由其他线程来强制中断或停止,而是应该让线程自己自行停止,自己来决定自己的命运,所以。
Thread .stop, Thread.suspend,Thread.resume都已经被废弃了。
中断
中断是一种协商机制,并不是发出中断命令后线程立即中断,而是由线程自行停止。
每个线程对象中都有一个中断标识位,用于表示线程是否被中断;该标识位为true表示中斯,为false表示未中断。通过调用线程对象的interrupt方法将该线程的标识位设为true。可以在别的线程中调用,也可以在自己的线程中调用。
| public void interrupt() |
实例方法 interrupt()仅仅是设置线程中断状态为true |
| public static boolean interrupied() |
静态方法 判断当前线程是否是中断状态,并重置中断状态为false |
| public boolean isInterrupted() |
实例方法 判断当前线程是否被中断(检查标志位) |
值得思考的是,我们来看下一段代码
try{ Thread.sleep(2000); } catch (InterruptedException e){ Thread.currentThread().interrupt();//为什么要在一场出再调用一次 e.printStackTrace(); }
这是因为interrupt的性质
当线程正常运行时,那么会将线程的中断标记变为true。
当线程在阻塞状态中(例如sleep、wait、join),那么线程会立刻退出阻塞状态,并抛出InterruptedException异常。(并不会转变中断标记状态)
那么如何中断运行中的线程呢?
- 通过volatile变量实现
- 通过AtomicBoolean
- 通过Thread自带的api实现
其中volatile和AtomicBoolean相当于一个flag,在线程外改变值,内部能接收到(if判断条件)
5.LockSupport类
LockSupport类是一个线程阻塞工具,它调用了Unsafe中的native代码,并提供了park()和unpark()方法
当调用park方法时,如果有凭证,则会直接消耗掉这个凭证然后正常退出。如果无凭证,就必须阻塞等待凭证可用。
unpark则相反,它会增加一个凭证。但凭证最多只能有1个。累加无效。
因此park和unpark必须出现并且park只能出现一次,因为无论多少个unpark只能存储一个凭证
它们并不像wait()和notify()方法一样必须一前一后,可以随意搭配。

浙公网安备 33010602011771号