AQSとThreadPoolExecutorの比較(対話ディスカッション形式の指示)

この記事はほとんど言葉でいっぱいです、まだもっと言葉があります、方法はありません、底に近いほど、より抽象的なです、辛抱してください。ボトルネックを突破したい場合は、落ち着くしかありません!

我:问个问题
		AQS
		通过CAS status变量,来控制锁对吧
		而且,里面维护了一个队列,用来,添加线程Node到队列中。。。
		由实现类来实现具体的获取锁的逻辑,和释放锁的逻辑
		那么ThreadPoolExecutor中的worker也是继承了AQS
		那么问题就来了,这里的Worker继承了AQS,貌似没有用它的队列
		因为,任务是添加到线程池的队列里。。。
		Worker自身作为线程,是添加到线程池的Hashset里面的
		那么,Worker是不是没有用AQS的队列了?
		哪位老铁出来聊聊
甲:他自己的队列应该也继承了aqs
我:谁的队列?
		@甲
		线程池的任务队列,没有继承AQS
		我个人感觉,我看代码,是觉得,Worker继承AQS主要是用了AQS的锁功能。。
		没用用它的队列存放线程的功能
		因为,现在线程都放到线程池了,不可能线程池在分配任务的时候,把多个线程去执				   行同一个任务。。
		否则线程池的队列就没起到作用了
乙:@我 概念有点混淆了
丙:膜拜大佬
我:@乙 帮梳理下
乙:AQS的队列是当多个线程获取同一个锁对象时,发现该锁对象被其他线程所占用时,会将当前线	程抽	象成一个节点放到AQS的CLH双向队列中,而线程池的Woker类他起到的作用就是帮忙从线程池的阻塞队列中不断获取任务去执行可以把这过程看成是一个串行的执行过程
丁:完全看不懂
丁:膜拜大佬
我:@乙 所以,Worker线程,每次只会执行一个任务
		不会,多次分任务给他
		当线程都在忙的时候,线程池,会把任务放到它自己的任务队列里面。。。
		所以,线程池中的任务,是不会发生线程竞争的。。。
		从而避免了,线程的上下文切换,这也是线程池的设计初衷之一。。
乙:@我 是的不会发生冲突
		你可以再看下线程池工作原理那块代码
		我记得woker类通过一个for循环去队列中拿任务
		每次取出一个去执行
我:好的
		我现在还有个忙点就是,这个worker继承AQS,主要用它的锁功能,那么,worker的锁用在什么地方了
		线程池自己有一把mainLock用来,同步线程去获取任务
乙:线程池的作用是复用创建好的线程,降低资源消耗,提高资源利用率,创建出来的线程去执行任务,操纵共享资源(也就是访问临界资源的时候)才会有线程安全问题,那线程安全的问题解决方法是什么呢?自然是加锁(lock,Synchorized)或无锁并发(CAS),现在拿加锁来说,如果对共享资源加锁后,别的线程要想访问是不是就不能访问了,这时候这个像访问的线程就需要加到CLH阻塞队列中
		这样逻辑是不是清晰一些
		我觉得woker类更多的是为了保证可见性
		@我 ...  这个worker继承AQS,主要用它的锁功能,那么,worker的锁用在什么地方了
		这块有没有去想过
		@我 有可能也是利用了lock的可中段特性

概要:
上記のダイアログを通じて、AQSとThreadPoolExecutorをより具体的に理解できます。

AQSは、CAS volitate状態変数を介してロック機能を実装します。同時に、CLHキューがあります。このキューには、競合するスレッドが格納されます。スレッドが競合しない場合は、キューに入り、待機します。特定のAQS実装クラスは、ここでのロック解除ロックのロジックは、実際には状態値を変更することです。

ThreadPoolExecutorにはWorkerスレッドクラスがあり、これもAQSを継承し、tpool自体にもキューworkQueueがあり、HashSetコレクションであるReentrantLockmainLockはtpool構造の一部です。

まず、WorkerスレッドクラスがAQSを継承することを説明しましょう。Workerは主にロック取得とロック解除機能を実現するためにAQSを継承します。この関数は、tpool内のスレッドが競合しないため、AQSキューが競合するためにも使用されます。待機中のスレッドを格納しません。つまり、WorkerはAQSのキュー機能を使用せず、ロック機能のみを使用します。
では、このワーカーロックはどこで使用されますか?

 也就这一个方法里面用到自己的锁
 final void runWorker(Worker w)

ここに画像の説明を挿入

tpoolにタスクが多すぎる場合、タスクはworkQueueに配置され、アイドル状態のスレッドがタスクを取得して実行するのを待ちます。

HashSetは、コアスレッドや緊急スレッドなどのスレッドをtpoolに格納するために使用されます

複数のスレッドがexecuteメソッドを一緒に呼び出す可能性があるため、mainLockはスレッドセットワーカー(HashSet)の同期に使用されます。現時点では、ワーカーにスレッドを追加するには同期が必要です。

とりあえずこのレベルしかわからないので、後で更新します。

あなたは学校を失いましたか?

おすすめ

転載: blog.csdn.net/Brave_heart4pzj/article/details/114915731