この道路アリババは、質問に直面しているマルチスレッドあなたが学びませんか?

注目点は、迷子にしないでください。Java関連のテクノロジーと継続的に更新情報!

ここに画像を挿入説明

序文

友人が面接アリ、ここで対象に遭遇し、あなたと共有トピックをマルチスレッド私に尋ねました。

直接テーマに騒ぎ、:

通过N个线程顺序循环打印从0至100,如给定N=3则输出:
thread0: 0
thread1: 1
thread2: 2
thread0: 3
thread1: 4
.....

いくつかのブラシは、多くの場合、確かに前に、次のトピックが遭遇した友人の質問に、直面しています:

两个线程交替打印0~100的奇偶数:
偶线程:0
奇线程:1
偶线程:2
奇线程:3

これら二つのトピックは、第二のトピックは少し単純なポイントである、我々はどのように二つのスレッドパリティ印刷について考え始めることができ、同様のようです。

印刷物の二つのスレッド奇数

一部の人々がここにあります各サイクルで行われますスレッド、によって循環簡単な方法は、奇数または偶数裁判官で使用してから、私たちが望む結果をプリントアウトすることがあります。ここでは、このことを議論するが、対象者の意図にもっと練習反します。

実際には、我々は二つのスレッドの実行順序を制御する必要がある。この問題を行うには、スレッドの実行が奇数 - 偶数のスレッドを実行した後、これはビット通知メカニズムのようなものです、でもスレッドは、スレッドが奇数通知し、奇数 - 偶数、その後、スレッドスレッドに通知します。そして、待機中の通知/の姿がそこに友人が待ちのオブジェクトを考えて、通知飛びました。次のようにはい、ここで私たちは待ってその実現に通知し、コードは次のとおりです。

public class 交替打印奇偶数 {
 static class SoulutionTask implements Runnable{
 static int value = 0;
 @Override
 public void run() {
 while (value <= 100){
 synchronized (SoulutionTask.class){
 System.out.println(Thread.currentThread().getName() + ":" + value++);
 SoulutionTask.class.notify();
 try {
 SoulutionTask.class.wait();
 } catch (InterruptedException e) {
 e.printStackTrace();
 }
 }
 }
 }
 }
 public static void main(String[] args) {
 new Thread(new SoulutionTask(), "偶数").start();
 new Thread(new SoulutionTask(), "奇数").start();
 }
}

ここでは、二つのスレッドを通して私たちに通知し、スレッドの実行を制御するのを待つ、と私たちの目標の結果をプリントアウトしてきました

N個のスレッドの印刷サイクル

答えのグループフレンズ後私にこの質問を助け、私達の元の質問、Nスレッドの印刷部数に戻り、再び投げ出さ内のグループでこの問題を入れて、古いドライバの多くを印刷する前にパリティを交互に読みこの質問は、その後、すぐにいくつかのバージョンを作った、私たちは古いドライバのコード1を見てみましょう:

public class 老司机1 implements Runnable {
 private static final Object LOCK = new Object();
 /**
 * 当前即将打印的数字
 */
 private static int current = 0;
 /**
 * 当前线程编号,从0开始
 */
 private int threadNo;
 /**
 * 线程数量
 */
 private int threadCount;
 /**
 * 打印的最大数值
 */
 private int maxInt;
 public 老司机1(int threadNo, int threadCount, int maxInt) {
 this.threadNo = threadNo;
 this.threadCount = threadCount;
 this.maxInt = maxInt;
 }
 @Override
 public void run() {
 while (true) {
 synchronized (LOCK) {
 // 判断是否轮到当前线程执行
 while (current % threadCount != threadNo) {
 if (current > maxInt) {
 break;
 }
 try {
 // 如果不是,则当前线程进入wait
 LOCK.wait();
 } catch (Exception e) {
 e.printStackTrace();
 }
 }
 // 最大值跳出循环
 if (current > maxInt) {
 break;
 }
 System.out.println("thread" + threadNo + " : " + current);
 current++;
 // 唤醒其他wait线程
 LOCK.notifyAll();
 }
 }
 }
 public static void main(String[] args) {
 int threadCount = 3;
 int max = 100;
 for (int i = 0; i < threadCount; i++) {
 new Thread(new 老司机1(i, threadCount, max)).start();
 }
 }
}

コアメソッドは内部で実行し、我々は見ることができるし、印刷は奇偶同様の原理交互に、我々はのnotifyAllが変更に通知する場合は、ここで多くの人々に注意を払う必要があり、他のスレッドがすべて実際には、実行されるようにのnotifyAllが理解お待ちしております、それは間違っています。ここだけにして再開されたスレッドが行います、生きるためのゲンロック同期ブロックで包まれ、私たちはここにいるために、また、ウェイクアップとして知られ、現在の待機状態を解除スレッドをお待ちしております同期ロックを奪うだろう。

この古いドライバのコードが実行を通じてんが、それはどのような問題がありますか?我々は最終的に再開されたスレッドが実行されるべき次の出現する可能性があるかどうかわからないと私たちの時間の多数のスレッドは、ロックをつかんだが、我々は自身の実行すべきでない場合は、その後、ケースを入力するのを待つ、例えば100は、今そこにありますスレッドは、その後、自分自身を見つけていない、最初の99個のスレッドをつかんで、その後、彼は実行された後、第2のスレッドの実行を必要とする、今最初のスレッドの実行ですが、つかむために最初の100スレッド、その後、自身が待つ入力しないことが判明しましたそして最後に待機した後、最初の98,97 ... 3つのスレッドをつかんされるまで、とに最後の目標を完了することが、それは、多くの白マルチプロセスを実行する第二のスレッド同期ロックをつかみました。
ここに画像を挿入説明
そこロック/条件でもこの機能を実現して、他の古いドライバがあるだけでなく、比較的新しい方法で行うには、このようなキューとして古いドライバは、当然のことながら、ここにない任意のより多くの、そして上記の一般原則に基づいて、私はここで言います私のアプローチは、いくつかの共通のシンクロナイザでのJavaマルチスレッドでは、このシナリオの下での使用セマフォのために、より適している、それは、セマフォで、私たちの次のスレッドのセマフォは信号を通じて、糸を保持しています関連配列の全体量が、次のように

static int result = 0;
 public static void main(String[] args) throws InterruptedException {
 int N = 3;
 Thread[] threads = new Thread[N];
 final Semaphore[] syncObjects = new Semaphore[N];
 for (int i = 0; i < N; i++) {
 syncObjects[i] = new Semaphore(1);
 if (i != N-1){
 syncObjects[i].acquire();
 }
 }
 for (int i = 0; i < N; i++) {
 final Semaphore lastSemphore = i == 0 ? syncObjects[N - 1] : syncObjects[i - 1];
 final Semaphore curSemphore = syncObjects[i];
 final int index = i;
 threads[i] = new Thread(new Runnable() {
 public void run() {
 try {
 while (true) {
 lastSemphore.acquire();
 System.out.println("thread" + index + ": " + result++);
 if (result > 100){
 System.exit(0);
 }
 curSemphore.release();
 }
 } catch (Exception e) {
 e.printStackTrace();
 }
 }
 });
 threads[i].start();
 }
 }

実行の各スレッドがあなたの手を再びできるように、インタビュアーは、場所をテストするためにこのように、我々は、我々が行うことに合意したために、各スレッドが、それも必要であるスレッドの無駄きっかけにはならないでしょう制御の下で、それはまたあなたのマルチスレッド知識が固体であることを確認することができます。

福祉

グループ番号:742 991 985
グループが検証に「CSDN」高度なJavaのアーキテクチャデータ、ソースコード、ノート、ビデオダボ、Redisの、ネッティー、ZooKeeperの、春の取得
クラウド、分散、並行性の高いアーキテクチャ技術アーキテクチャのビデオを

あなたが助けがあることを感じた場合は、奨励するために私にいくつかの賞賛を与えてください!

おすすめ

転載: blog.csdn.net/XingXing_Java/article/details/91955441