J.U.C之aqs
线程池
线程池有很多种这里演示CachedThreadPool
ExecutorService executorService = Executors.newCachedThreadPool();
for(int i=0;i<threadCount;i++){
executorService.execute(()->{
});
}
CountDownLatch
理解为线程计数器
CountDownLatch是通过一个计数器来实现的,计数器的初始值为线程的数量。每当一个线程完成了自己的任务后,计数器的值就会减1。当计数器值到达0时,它表示所有的线程已经完成了任务,然后在闭锁上等待的线程就可以恢复执行任务。
CountDownLatch countDownLatch =new CountDownLatch(1000); //初始化1000线程计数器
countDownLatch.countDown(); //表示countDownLatch计数减少
countDownLatch.await(); //表示检查countDownLatch若不为0则阻塞,为0,则允许执行(用光了才继续进行)
Semaphore
理解为线程信号量
Semaphore semaphore =new Semaphore(3); //初始化三个许可
semaphore.acquire(); //获取许可
semaphore.release(); //释放许可
semaphore.tryAcquire() //尝试获取许可,成功返回true 也可以加入参数获取许可个数
semaphore.tryAcquire(5000,TimeUnit.MILLISECONDS); //5秒超时时间,超时不候
CyclicBarrier
通过它可以完成多个线程等待,只有所有线程都准备就绪后才能各自继续执行,他和countdownlatch有些相似,都是通过计数器来实现的,当某个线程调用了await方法后,线程进入等待状态,而且计数器执行加一操作。当计数器的值达到初始值后,所有线程才会被唤醒。而且cycliBarrier调用reset后可以循环使用。举例来说,cyclibarrier可以用来多个线程分别计算数据,最后所有结果合并计算。
CycliBarrier和CountDownLatch的区别
1)countDownLatch的计数器只能使用一次,而cycliBarrier计数器可以使用reset方法重用
锁的实现2)countDownLatch的使用场景一般是一个或n个线程需要等待其他线程完成某项操作之后才能继续执行,而cycliBarrier描述的是多个线程相互等待,直到所有线程都满足条件才继续执行
-----------------------------------------------------------------------------
ReentrantLock与锁
ReentrantLock(可重入锁)和synchronized区别
1.ReentrantLock可以指定是公平锁还是非公平锁
2.ReentrantLock提供了一个Condition类,可以分组唤醒需要唤醒的线程
3.ReentrantLockt提供能够中断等待锁的线程机制,lock.lockInterruptibly();
4.但是ReentrantLock必须要释放锁操作,否则容易发生死锁。在这点synchronized就不需要,而且synchronized兼容性更好,在更老的版本依然可以使用
一般情况下当只有少量进程的时候建议使用synchronized,当线程数很多但是能够预估的情况下建议使用ReentrantLock。
synchroized由jvm控制一般不会引发死锁,而ReentrantLock使用不当,则容易引发死锁
Lock lock =new ReentrantLock(); //初始化锁
lock.lock(); //上锁
lock.unlock(); //解锁
ReentrantReadWrite Locklock =new ReentrantReadWriteLock(); //初始化读写锁
Lock readLock =lock.readLock(); //初始化读锁,写锁同理
readLock.lock(); //读锁上锁
readLock.unlock(); //写锁解锁
StampedLock stampedLock = new StampedLock();
long stamp = stampedLock.writeLock(); //上锁
stampedLock.unlock(stamp); //解锁
网友评论