并发编程中有俩大问题

  • 互斥(即同一时刻只允许一个线程访问共享资源)
  • 同步(即线程之间如何通信、协作)

信号量和锁与conditon一样也是解决互斥和同步

信号量一共有三个原子方法(基于CAS实现)

init up down 分别对应Java中Semaphore中的
构造方法,acquire release

java 中默认初始化Semaphore是非公平的 因为非公平的性能高

对于非公平锁和公平锁,这两种锁都有等待队列,但是区别在于非公平锁允许线程不先出入队而是先尝试获得锁,这一点上公平锁需要扫描等待队列,源码上也直接反映了这一点。去掉这个功能的话公平锁和非公平锁也无甚差异。

实现互斥的原理

还是计数器,init的时候初始化计数器值,执行up计数器减一,执行release加一,
当计数器<=0则阻塞。

实现同步的原理

release后其他线程继续执行。注意这里只能唤醒一个线程去执行。

为什么有了锁还要用信号量?

因为信号量可以允许多个线程同时访问 应用场景主要是一些池化技术 比如数据库连接池,可以允许多个线程同时去访问共享资源,提高性能。 比如连接池一共10个连接,如果有11个线程来获取, 你肯定希望第11个线程等待,而不是失败。

课后思考

因为ArrayList不是线程安全的,多个线程同时访问共享资源会有线程安全问题。