最近忙着毕设,要做前端,所以看更多的是React的知识,小后端🐶还是要继续学习总结,不然就要没(tou)时(lan)间继续写了。
Semaphore
中文含义是信号量,它是synchronized的升级版。
synchronized 关键字,代表这个方法加锁,相当于不管哪一个线程(例如线程A),运行到这个方法时,都要检查有没有其它线程B(或者C、 D等)正在用这个方法(或者该类的其他同步方法),有的话要等正在使用synchronized方法的线程B(或者C 、D)运行完这个方法后再运行此线程A,没有的话,锁定调用者,然后直接运行。它包括两种用法:synchronized 方法和 synchronized 块。(度娘解释)
Semaphore主要的作用是控制线程的并发数,如果单纯的使用synchronized是不能实现的。
简单看
|
|
Semaphore结构
|
|
两个构造方法:
参数permit是许可的意思,代表在同一时间内,最多允许多少个线程同时执行acquire()和release()之间的代码,Semaphore发放许可的操作是减法操作。
参数fair,表示内部使用的是FairSync(公平锁)或者NonfairSync(非公平锁),表示每次线程获取锁的机会是否是公平的,具体的可以看底层实现,继承自AbstractQueuedSynchronizer,通过state判断是否是加锁状态,state 为0,表示锁未被获取,不为0,表示已被获取。
如何用
第一种,同步的执行一个任务(与Synchronized相似)
|
|
这种比较简单,就不深入展示了,要看的是在多个线程下如何控制并发数量。
第二种,控制线程并发数量
首先是执行类
创建一个线程池,分配任务:
执行结果:
可以看到,在设定的线程睡眠5秒内,只有两个线程同时执行acquire()和release()之间的逻辑,通过Semaphore控制了线程的并发数量。
其它方法
- acquire(int) : 一次获取多个许可
- acquireUninterruptibly() : 使等待进入acquire()方法,不允许被终止
- tryAcquire() : 尝试地获得一个许可,如果获取不到就返回false,通常与if判断使用,具有无阻塞的特点
- tryAcquire(long timeout, TimeUnit unit) : 多少时间内获取不到许可就放弃
还有很多方法,诸如availablePermits()/drainPermits()/hasQueuedThreads()/getQueueLength()等,感兴趣的话请怒开IDE查看具体实现吧。
CountDownLatch
CountDownLatch也是一个工具类,可以使线程同步的处理上更加灵活,CountDownLatch也是减法操作。
简单介绍
|
|
举个🌰:
来了一辆小汽车,要等满5个人才开车,来了1个,不开;再来1个,还是不开,最后5个人到齐了,开车开车。
类结构&构造方法
参数count表示要等待的数量
方法示范
执行类,等待5秒后执行countDown
运行类
执行日志:
可以看到,在线程池控制1个并发线程,poolExecutor提交任务之后打印日志,但是countDownLatch.await()方法之后的代码,因为count没有减到0,不能执行。
在TestService方法中,每隔一秒执行countDownLatch.countDown()方法,最后十个线程跑完,count减到0,countDownLatch.await()方法之后的代码才可以执行。
方法
- await() : 等待
- countDown() : 计数减一
- await(long timeout, TimeUnit unit) : 在限定时间内进行等待,超过时间返回false
- getCount() : 获取计数count
小结
Semaphore作为信号量,用来控制线程的并发数量,CountDownLatch用来控制线程执行任务的时机也挺不错的。它们两个的理解和使用都比较简单,好了,又填了一个坑,下次继续挖坑和填坑hhh