继续面试大纲系列文章。
这是多线程的第二篇。
多线程就像武学中对的吸星大法,理解透了用好了可以得道成仙,俯瞰芸芸众生;而滥用则会遭其反噬。
在多线程编程中要渡的第二个“劫”,则是Lock。在很多时候,包括面试、包括实际项目应用,我们都会拿来和synchronized对比一番。
我们知道,多线程的核心思想是通过增加线程数量来并发的运行,来提高效率,也就是数量决胜论,而不是质量决胜(提高每个线程的处理能力)。多线程编程中面临的最大挑战,是如何解决多个线程同时修改一个公用的变量所带来的变量值不确定性问题。顺着这个思路分析,常用办法,无非就是,要么对变量动手,在一个线程修改时,变量值被锁定。要么是对修改的操作动手,在该段代码执行时,对其加锁,其他线程不可以在同一时刻进入该段代码执行。
同synchronized一样,Lock,也是实现了后一种办法。只不过,实现方式,有所不同。
public class Mutex implements Lock {
// 静态内部类,自定义同步器
private static class Sync extends AbstractQueuedSynchronizer{
// 该方法用于判断当前锁是否在独占模式下被占用状态
protected boolean isHeldExclusively(){
return getState() == 1;
}
// 获取锁!!!
public boolean tryAcquire(int acquires){
//典型的CAS原子操作,如果初始状态为0,可以获得锁
if (compareAndSetState(0, 1)){
setExclusiveOwnerThread(Thread.currentThread());
return true;
}
return false;
}
//释放锁,将当前状态设置为0
protected boolean tryRelease(int releases){
if (getState() == 0){
throw new IllegalMonitorStateException();
}
setExclusiveOwnerThread(null);
setState(0);
return true;
}
// 返回一个Condition,每个condition都包含了一个condition队列 ,这个后续再说
Condition newCondition(){
return new ConditionObject();
}
}
4.扩展:Condition,多路通知机制