工具类
2021-07-01 本文已影响0人
水木共美
1、Phaser CountDownLatch CyclicBarrier Semaphore
- CountDownLatch
public CountDownLatch(int count) // 构造器 倒计时的计数器
public void await() throws InterruptedException // 这两个await方法会检测现在count值是否为0,如果为0则直接返回,不为0,则会将当前线程挂起,知道count为0唤醒线程,返回
public boolean await(long timeout, TimeUnit unit) throws InterruptedException
public void countDown() // 减1 实现是使用的compareAndSetWaitStatus CAS 负责唤醒await的线程
应用:
等待多个任务执行完成后,再执行一个任务
如:以前的app上,多张图片同时上传,全部上传完成再后调用信息上传接口
- CyclicBarrier
public CyclicBarrier(int parties) // 构造器 需要等待多少个线程到达 cyclic的含义是可复用
public CyclicBarrier(int parties, Runnable barrierAction)
public int await() // 等待parties个线程走到这里,然后再一起放行往后
public int await(long timeout, TimeUnit unit)
应用:
使用上面那个barrierAction可以达到countdown的目的。。
如一辆客车必须装满才能让乘客上车,每个乘客一个线程,当到达客车容量20人时,放开这些乘客,让他们上车买票坐车。
- Semaphore
public Semaphore(int permits) // 构造器 限制同时通过的数量,获取后需要自己释放 fair指是否是公平锁即先到先得
public Semaphore(int permits, boolean fair)
public void acquire() throws InterruptedException // 获取1个许可 -- 阻塞的,会一直等待
public void acquire(int permits) throws InterruptedException // 获取permits个许可 -- 阻塞的,会一直等待
public void release() // 释放1个许可
public void release(int permits) // 释放permits个许可
// 下面这4个是非阻塞获取许可和超时阻塞获取
public boolean tryAcquire()
public boolean tryAcquire(long timeout, TimeUnit unit)
public boolean tryAcquire(int permits)
public boolean tryAcquire(int permits, long timeout, TimeUnit unit) throws InterruptedException
应用:限流请求数量
- Phaser
public Phaser() // 构建相移器,标识需要parties个到达才能往下走 可以通过register添加parties的数量
public Phaser(int parties)
public Phaser(Phaser parent)
public Phaser(Phaser parent, int parties)
public int register() // parties加1
public int arrive()// 只标记到达,不等待
public int arriveAndAwaitAdvance() //标记到达并阻塞等待下一阶段
public int arriveAndDeregister() //到达并将自己注销
可以用多次CyclicBarrier实现Phaser的阶段请求
但是CyclicBarrier不能动态修改parties
应用:几个人参加多个运动比赛,需要每个人都到达,才能开始短跑比赛,需要每个人短跑完了,才能开始长跑,需要每个人都长跑完了,才能开始跳远。。。
2、ArrayList的线程安全版本
CopyOnWriteArrayList
Collections.synchronizedList(List list) 返回一个线程安全的SynchronizedList :实现synchronized (mutex)
3、auto increment
mysql
5.1.22 之前 表锁
5.1.22之后 innodb_autoinc_lock_mode
- 为0时,跟以前一样,表锁
- 为1时
a简单插入时,根据要插入的数量,计算出需要分配的id数,只锁分配id的过程
b insert select 不能直接推测出要插入的数量,和以前一样直接锁表
c INSERT INTO t1 (c1,c2) VALUES (1,’a'), (NULL,’b'), (5,’c'), (NULL,’d');
INSERT … ON DUPLICATE KEY UPDATE
不确定最终插入多少条,但是直到最坏条数,所以分配最坏条件下的条数,只分配id过程锁住 - 为2时
不做预分配,来一个,锁一个分配过程
两个insert语句的id分配可能会交叉,如果做主从的话,会导致主从的id不一致
默认值时1
insert 。。。select 会发生锁表