1)管程在SDK包中是怎样实现的?

  • 靠Lock和Condition接口,Lock用来解决互斥的问题 ,Condition用来解决同步的问题。

2)java语言层面已经有sychronized来 实现管程了,那为什么我们的sdk工具包中还要再实现一遍管程,直接用sychronized不就行了吗?

  • sychronized这个语言层面的设计是有瑕疵的,我们说解决死锁有个方法:破坏不可强行剥夺条件。那我们的sychrnized他如果获取不到资源,他会带着已申请到的资源进入阻塞队列去排队,如果他带进去的资源刚好是另外一个线程苦苦等待的,那就可能造成死锁 。

3)怎样去优化我们synchronized修饰的线程带着资源进阻塞队列排队这个问题呢?

  • 首先这个 排队线程要 能够收得到消息 ,对应计算机层面就是响应中断。
  • 其次啊,要让它能够有个超时机制,获取不到进一步资源的话,再等等嘛,实在等不到返回个错误也行,就是不要带着已有资源去阻塞队列睡大觉 。让别人也不好过。
  • 最后可不可以设计成如果获取不到进一步的资源,不要进入阻塞队列,而是直接返回,并且交出已有资源。

4)上面的三个设计方案对应到我们的SDK工具包之中是怎样实现的?


// 支持中断的API
void lockInterruptibly()
throws InterruptedException;
// 支持超时的API
boolean tryLock(long time, TimeUnit unit)
throws InterruptedException;
// 支持非阻塞获取锁的API
boolean tryLock();

5)我们说sychronized保证可见性是根据happen-before规则,那现在工具包中的这些设计是如何保证可见性的呢?

  • ReentrantLock底层有一个volatile类型的成员变量state。加锁和解锁之前都去读一下这个变量,从而就利用volitile来保证可见性。

6)什么是可重入锁呢?

  • 可以嵌套使用的锁
A加锁{
A又加锁{
}
}

7)什么是公平锁和非公平锁?

  • 在队列中排队,如果cpu空闲的时候,是排在第一个的 先去 用那就是公平锁,否则就是不公平的锁。
  • 对应到具体代码,我们的reentrantLock可以带布尔类型的参数,true的话就是一把公平锁,false或者不填就是一把不公平的锁 。

8)关于锁,老前辈们有哪些最佳实践方案?

  • 在更新一个对象的共享变量的时候需要上把锁。
  • 在读取一个共享变量的时候也需要上把锁。
  • 在调用其它对象的方法的时候千万不要用锁,万一他这个对象方法里面有一些操作,可能会造成死锁。