指定された順序で実行する複数のスレッドを同期する方法

今日、私は面白いインタビューの質問を見て、どのように複数のスレッドが設立された順序で実行されている作るには?例えば、各スレッドは、整数を出力し、

だから、これで期待:。0,1,2,3,4,5,6,7,8,9代わりの0,2,4,1,3,5,8,7,9,6

一見すると、これは、抗試験の人間がそうではないのですか?すでに有名なアウトオブオーダー実行をマルチスレッド。それぞれのコードを達成するためのソリューションの3種類を考え、一瞬のために一時停止します。

 

方法1 newSingleThreadExecutor

newSingleThreadExecutorリターンは、スレッドプールのスレッドを1つだけ含まれている場合、このexecutorに複数のタスク、スレッドプールは、タスクを終了した後、これの実行に提出する実行順序を、確実に、次のタスクを処理した後。現在のスレッドが予期せず終了した場合、それはタスクを実行し続けるために、新しいスレッドを作成します。

次のようにサンプル・コードは次のとおりです。

ExecutorServiceのプール= Executors.newSingleThreadExecutor()。
        以下のためにint型 0 = Iを、I 1000 <; ++ I){
             最終 int型の数= I。
            pool.execute(() - > {
                System.out.println( +の「私は」数)。
            });
        }
pool.shutdown();

 

結合を使用して方法2方法

我々はスレッドオブジェクトを使用してこのメ​​ソッドを呼び出すと呼ばれるオブジェクトの実行が終了するまで、それは、呼び出し元のスレッドの実行を中断します。

英語のオリジナルは理解しにくい、発音するのは非常に困難です。簡単に言えば、通話が参加するスレッドである、他のスレッドは素直などAは実行に仕上げなければなりません。

次のようにサンプル・コードは次のとおりです。

パブリック クラス労働者は、実装{Runnableを

    プライベート int型の数。
    公共労働者(int型I){
        番号 = I;
    }
    
    @オーバーライド
    公共 同期 ボイドの実行(){
        System.out.println( +の「私は」数)。
    }
}
パブリック クラスTestWorker {

    パブリック 静的 ボイドメイン(文字列[]引数){
        
        INT J = 0; J <1000; ++ j)は{
            スレッドスレッド = 新しいスレッド(新しい労働者(J));
            thread.start();
            してみてください{
                thread.join();
            } キャッチ(InterruptedExceptionある電子){
                e.printStackTrace();
            }
        }
    }
}

 

方法3を使用ThreadPoolExecutorは、スレッド1の中核番号を設定しました

次のように私たちはまず、そのコンストラクタをThreadPoolExecutorを分析します

公共ThreadPoolExecutor(int型corePoolSize、

                              int型maximumPoolSize、

                              長いkeepAliveTimeが、

                              TimeUnitでユニット、

                              BlockingQueueの<Runnableを>ワークキュー、

                              ThreadFactory threadFactory、

                              RejectedExecutionHandlerハンドラ)

次のように各パラメータは以下のとおりです。

1、corePoolSizeがcorePoolSizeに達するまで、スレッドのコアの数は、スレッドプール内のスレッドの現在の数を検出するためにジョブの投入があった場合等の提案とコアCPUの数は、タスクを実行する新しいスレッドcorePoolSizeワード未満です。場合、スレッドプール内のスレッドの数は以上corePoolSize、ワークキュー待ちにタスク。

2、maximumPoolSize以上行わ拒絶ポリシー場合は、スレッドプール内のスレッドの数は、新しいmaximumPoolSize未満である場合、キューがいっぱいである、スレッドプール内のスレッドの最大数。

3、keepAliveTimeがあなたが60代を設定した場合、スレッドがアイドル60年代になった後、最大スレッドアイドル時間は、自動的に終了します。

ユニット、その上の分、秒との時間。

図4は、ワークキューは、スレッドの数よりも多くのタスクを格納する場所をcorePoolSize。

5、threadFactory、スレッドの工場出荷時のデフォルトとすることができます。

6、ハンドラは、ポリシーが拒否、直接スローAbortPolicy、例外を4種類を分け、DiscardPolicy静かに実行されずに放棄、CallerRunsPolicy(呼び出し側の実行):タスクを放棄しないだろうどちらもこのポリシーが例外をスローしませんが、このタスクが返されます呼び出し元に、新たな作業の流れを減少;, DiscardOldestPolicyは(最も古いを捨てます)

 次のようにサンプル・コードは次のとおりです。

ExecutorServiceのプール= 新しい ThreadPoolExecutor(1 1000、300 、TimeUnit.SECONDS、 
                 新しい LinkedBlockingQueue <Runnableを>(1,000 )、Executors.defaultThreadFactory()、 
                 新しいThreadPoolExecutor.AbortPolicy())。
        以下のためにint型 0 = Iを、I 1000 <; ++ I){
             最終 int型の数= I。
            pool.execute(() - > {
                System.out.println( +の「私は」数)。
            });
        }
pool.shutdown();

 

4.結果を実行します

私は午前0時
私は午前1時
私は午前2時
私は午前3時
私は午前4時
私は午前5時
私は午前6時
私は、午前7時
私は午前8時
私は午前9時
私は午前10時

...

私は990です
私は991です
私は992です
私は993です
私は994です
私は995です
私は996です
私は997です
私は998です
私は999です

 

おすすめ

転載: www.cnblogs.com/sankt/p/11695676.html