并发编程中有俩大问题
- 互斥(即同一时刻只允许一个线程访问共享资源)
- 同步(即线程之间如何通信、协作)
信号量和锁与conditon一样也是解决互斥和同步
信号量一共有三个原子方法(基于CAS实现)
init up down 分别对应Java中Semaphore中的
构造方法,acquire release
java 中默认初始化Semaphore是非公平的 因为非公平的性能高
对于非公平锁和公平锁,这两种锁都有等待队列,但是区别在于非公平锁允许线程不先出入队而是先尝试获得锁,这一点上公平锁需要扫描等待队列,源码上也直接反映了这一点。去掉这个功能的话公平锁和非公平锁也无甚差异。
实现互斥的原理
还是计数器,init的时候初始化计数器值,执行up计数器减一,执行release加一,
当计数器<=0则阻塞。
实现同步的原理
release后其他线程继续执行。注意这里只能唤醒一个线程去执行。
为什么有了锁还要用信号量?
因为信号量可以允许多个线程同时访问 应用场景主要是一些池化技术 比如数据库连接池,可以允许多个线程同时去访问共享资源,提高性能。 比如连接池一共10个连接,如果有11个线程来获取, 你肯定希望第11个线程等待,而不是失败。
课后思考
因为ArrayList不是线程安全的,多个线程同时访问共享资源会有线程安全问题。