1、Semphore计数信号量
- semphore是一个计数信号量
- semphore包含了一组许可证
- semphore有两个核心方法:
- acquire():从信号量中获取一个许可,进入阻塞状态。
- release():释放持有许可证的线程;
- 然而,实际上并没有真实的许可证对象供线程使用,Semaphore只是对可用的数量进行管理维护
- 总结:如果线程要访问一个资源就必须先获得信号量。如果信号量内部计数器大于0,信号量减1,然后允许共享这个资源;否则,如果信号量的计数器等于0,信号量将会把线程置入休眠直至计数器大于0.当信号量使用完时,必须释放
2、Synchronized同步隐式锁+wait()+notifyAll()
- synchronized加锁解锁的过程是隐式的,用户不用手动操作,优点是操作简单
- wait(): 使当前线程阻塞,前提是 必须先获得锁
- notify():只唤醒一个等待(对象的)线程并使该线程开始执行。所以如果有多个线程等待一个对象,这个方法只会唤醒其中一个线程,选择哪个线程取决于操作系统对多线程管理的实现
- notifyAll ():会唤醒所有等待(对象的)线程
在多线程中要测试某个条件的变化,使用if 还是while?
ReentrantLock需要手动加锁和解锁,且解锁的操作尽量要放在finally代码块中,保证线程正确释放锁。
- lock.lock():给当前线程上锁
- 利用ReentrantLock可重入锁创建多个Condition分别控制多个线程
- Condition c1=lock.newCondition();
- c1.await()使当前线程进入阻塞状态
- c1.signal()释放指定的线程
- lock.unlock():进行解锁操作
- 主要利用CAS+AQS队列来实现,CAS(Compare And Swap)比较并交换,CAS有3个操作数:内存值V、预期值A、要修改的新值B。当且仅当预期值A和内存值V相同时,将内存值V修改为B,否则什么都不做。
4、LockSupport类
- LockSupport核心类的方法就两个:
- part() :使当前线程阻塞,
- unpark():唤醒指定线程进行调用
- LockSupport类使用了一种名为Permit(许可)的概念来做到阻塞和唤醒线程的功能,可以把许可看成是一种(0,1)信号量(Semaphore),但与 Semaphore 不同的是,许可的累加上限是1。初始时,permit为0,当调用unpark()方法时,线程的permit加1,当调用park()方法时,如果permit为0,则调用线程进入阻塞状态。