CyclicBarrier详解
在上一篇的文章中有提到过 CountDownLatch ,其实 CyclicBarrier 也有异曲同工之妙,不过 CyclicBarrier 是等到所有的线程都到达一个点以后,然后再一起执行
有点像小时候一起去春游,必须等到所有的同学都到了学校,才能一起去坐车,不然就会一直等待。
构造函数
CyclicBarrier 的构造函数有两个,分别如下:
1 | public CyclicBarrier(int parties) { |
在上一篇的文章中有提到过 CountDownLatch ,其实 CyclicBarrier 也有异曲同工之妙,不过 CyclicBarrier 是等到所有的线程都到达一个点以后,然后再一起执行
有点像小时候一起去春游,必须等到所有的同学都到了学校,才能一起去坐车,不然就会一直等待。
CyclicBarrier 的构造函数有两个,分别如下:
1 | public CyclicBarrier(int parties) { |
如果想子线程想使用父线程的 ThreadLocal,那么父线程中的 inheritableThreadLocals 有值,这样子线程中的 init 方法就会自动的将父线程的 inheritableThreadLocals 设置为 ThreadLocal
但是因为子线程是在 init 方法中进行赋值的,所以如果子线程是由线程池创建的,那么该方法就又可能会失效,当线程池刚初始化完毕的时候,此时线程池中的还没有线程,当调用 execute
方法,此时就会 new 一个线程,那么这时候子线程是可以读取到父线程中 inheritableThreadLocals 的值
但是线程池中的线程是可以被复用的,所以后续如果线程不再创建的时候,那么子线程便不能再次获取父线程中的 inheritableThreadLocals,也就无法再将 ThreadLocal 进行父子线程的传递
从细节上来说,锁分为 乐观锁、悲观锁
乐观锁适用于读多写少的场景,一般是通过 CAS 进行操作,因为不用加锁,所以性能上比悲观锁优秀太多
悲观锁适用于写多读少的场景,性能开销比较大。
今天在看《现代操作系统》P73页的一个关于多线程的竞态条件的时候书中说到了唤醒等待位方法
,这个方法使我突然想起联想到以前在Java多线程中sleep()方法会清除中断状态的一些类似之处:
树上的代码:
1 |
|
在书中提到过一个情况就是:当消费者判断count==0的时候是会睡眠的,但是此时由于某种情况(线程的sleep()方法还没被执行完),而恰巧生产者又生产了一个item,导致此时count加一为1,而当count为1的时候生产者是会发出一个wakeup信号给消费者的,此时,由于消费者并没有睡眠因此会忽略掉该信号,而当消费者真正睡眠之后又由于生产者再不会进行通知,导致队列被生产者塞满,从而该模型阻塞。
那么为了解决该方法,书中引入了唤醒等待位方法
,该方法就是在生产者发出信号给消费者的时候添加一个中断状态,而当该线程需要进行睡眠的时候会先判断状态,若是wakeup则不进行睡眠