ロケットシーンからJavaのマルチスレッドのロックオブジェクトを学ぶために

ロケットシーンからJavaのマルチスレッドのロックオブジェクトを学ぶために

カウントダウンシーン

当社の開発プロセスでは、時々、カウントダウンカウンタに使用します。最も簡単なものは次のとおりです。int型のサイズ= 5;実行後、サイズ - は、この方法を実装しました。しかし、マルチスレッドの場合には、この操作は安全ではないだろう。現実の中で最も代表的な例:ケースロケット。

私たちは生きてロケットの打ち上げにそれを見てきました。送信する際に、多くのデバイスがあるロケッツは、すべての準備ができているかどうかを確認する必要があります。マスターコントロールルームは、すべての機器を準備した後、それは注文を起動します。また、ロケットのテストが必要であり、これは1つのチェックによって部門1が、部門のシナジー実現の数ではありません多くのデバイスがあることを知っています。部門は、言葉の異なるスレッドとして見た場合。我々は仮定することができます:

デバイスは、シングルスレッド動作でチェックの分割がある場合。

部門のシナジーの場合は数が、そして、それはマルチスレッドです。

そのため、複数のスレッドで行われたロケットを起動する前に、機器を確認してください。

私たちは、さまざまな複雑さは、さまざまな部門の設備をチェックする責任があり、異なる速度を知らない、いくつかの部門では、いくつかの部門が徐々に行われるチェック、検査の迅速な完了につながります。異なるスレッドがCPUリソースの競合するとき、我々は別のものとして理解することができます。このプロセス。

5つの部門は、5つの部門が一連の操作として見ることができる動作し、同時に一緒に仕事があるとします。異なる速度なので、コマンド・マスター・コントロール・ルームは、検査対象がそれを完了するとしているの立ち上げを発表しましたか?部署や部門がBまたはD部門である?いいえは、コマンドを発行したマスター・コントロール・ルームには5つの部門がチェックされ、放射が発行されます得るために送信されます。我々はまた、操作が完了する前に実行されているこのグループ(5つの部門)を取得のマスター・コントロール・ルームとして理解することができます。この時点で、マスターコントロールルームには5つの部門のグループは、スレッドグループを理解することができ、スレッドとして理解することができます。

上記の実際のケーススタディから、我々は、上記の動作Javaプログラミングを達成する方法を考えますか?

凱歌のJavaによって投稿この記事(kaigejava)オリジナル

COUNT-を達成するためのコードを使用して、

さまざまな分野でのシミュレーションのスレッド:

0fBJSPFDE6i

のは、従来見てみましょう。効果count--を使用してください。

メインスレッドのアナログマスターコントロールルーム:

0fBJSPme58S

上記のコードから、我々はカウンターカウントが0に達すると、マスターコントロールルームが発射命令を出したことがわかります。この論理的に言えば、それは正しかった、全く問題ありません。結果で見てみましょう:

結果:

0fBJSQOmAls

从运行结果,我们可以看到,当总控室接收到count =0的指令后,认为各个部门都已经检查完毕了。所以就下达了发射命令。但是在最后,我们发现火箭已经发射了,部门4和5才向总控室汇报检查完毕,准备就绪。这种情况是很危险的。因为我们知道火箭的造价是很昂贵的而且凝聚了很多科研人员的心血。如果因为某个部门未检查完毕就发射而导致火箭发射失败或者坠落,在现实生活中,这种情况是不允许出现的。

那么这种情况,在Java中,怎么解决呢?可以使用countdownlatch这个对象来解决。

Countdownlatch

Countdownlatch是什么?

先来看看源码中怎么解释的:A synchronization aid that allows one or more threads to wait until a set of operations being performed in other threads completes.

什么意思呢?

简单的来说,是一个同步辅助工具类,运行一个或多个线程在等待其他线程完成一组操作后再接着执行的工具类。

实现的流程:

通过一个计数器来实现的,计数器的初始值就是要执行的线程的数量。每当一个线程执行完毕之后,计数器的值就会减一,当计数器的值减少到0的时候,表示所有的线程都执行完毕了。然后再闭锁上等待的其他线程就可以恢复正常工作了。

来看看主要的方法

0fBJSQpdmIi

说明:

Sync:是countdownlatch内部类,继承AbstractQueuedSynchronizer使用AQS状态来代替计数的。

有参构造器:public CountDownLatch(int count){}

await():等待方法。还有一个带参数重载的方法。

countdown():执行计数器减1操作的方法。

使用countdownlatch模拟火箭发射前准备代码:

我们来看看使用countdownlatch来模拟火箭发射前准备会不会出问题。

来看看模拟部门的线程代码:

0fBJSRE3MDQ

为了保证计数器减一操作不受子线程运行结果影响,讲count.coundDown()操作放在finally代码块里面。

再来看看总控室下达发射命令的主线程:

0fBJSRfjoQa

在downLatch.await()之后,下达发射命令。

查看运行结果:

0fBJSS7Gifo


我们可以看到,当所有部门都准备就绪后,总控室接收到完成的指令后,下达发射火箭命令。这个流程才是正常的。从运行结果来看也是正常的。

使用场景:

场景1:某线程在运行前需要等待其他N个线程执行完成之后在执行。

比如:

容器启动spring 容器的启动,需要初始化、bean装配、检查其他依赖等加载完毕之后,在主线程在继续执行;

在比如:电商中统计库存问题。我们知道,一个电商项目有很多分类,不同分类下的库存不一样。如果要统计当前剩余总库存。这个时候,就可以使用其他线程统计每个分类下的库存。等所有分类都统计完成之后,主线程在进行汇总操作。





おすすめ

転載: blog.51cto.com/kaigejava/2479576
おすすめ