序文
プログラムの複数の部分を並列に実行できる場合、いくつかの問題のために、バックは非常に便利でも必要になってきている、これらは同時に又はマルチプロセッシング環境で同時に実行することの一部であるように見えます。並行編集プログラムの実行速度が大幅に向上、または使用の容易さを提供するためのモデルのために設計されたプログラムの特定のタイプすることができます。タスクが互いに並列に実行されたときに相互に干渉し始め、実際の並行性の問題が発生しました。
まず、同時多面的な
並行性の問題の解答は、二つの「新を管理するために設計された」「スピード」とに分けることができます。
1.より速く実行
より高速な実行をしたい、複数のプロセッサを必要とし、それが同時マルチプロセッサのプログラミングのための不可欠なツールです。なお、プログラムは、ユーザ要求多数のCPUの複数に分配することができる要求ごとにスレッドが割り当てられ、強力なマルチプロセッサWebサーバーを使用するのが一般的です。
単一のプロセッサ上で同時に実行する場合、オーバーヘッドがあるため、コンテキストスイッチのコストアップで、実行大きなオーバヘッドのオーダーよりも大きくてもよいです。しかし、ブロッキングは問題が異なるものとなる可能:プログラムは、プログラムの制御外の特定の条件が(のような:I / O)ため、タスクであれば、鉛を継続することはできませんが、タスクのスレッドがブロックされました。ノー同時場合は、プログラム全体が停止されます。そのため、タスクがシングルスレッドのプロセッサ・マシン上で同時使用をブロックしませんがあればどんな意味がありません。一般的に窓に使用されるスレッドの同時動作。
Javaのような並行システムの間でこれらのリソースの使用は、メモリやI / Oなどの共有リソースを使用しますので、私たちはこれらのリソースがないように、最も基本的な課題は、タスクを駆動する別のスレッドを調整することで、マルチスレッドプログラムを書きます複数のタスクを同時にアクセスします。
2.改善されたコードの設計
単にあなたの例を与える、より多くのNPCのゲーム内で、それぞれ独自に行きます。
糸の第二に、基本的なメカニズム
並行プログラミングは、私たちが実行している別の、独立したタスクの数にプログラムできるということです。マルチスレッド機構を介して、これらのタスクとは独立して、実行の各スレッドによって駆動されます。スレッドは、単一のプロセスであるため、したがって、1つのプロセスが複数のタスクの同時実行を持つことができ、流れを制御するが、プログラムはように一人一人が自分のCPUを持って望んでいます。基本的なメカニズムは、CPUタイムスライスです。
1.タスクの定義
スレッドは、タスクを駆動することができますので、あなたは、Runnableインタフェースによって提供することができるタスクを、記述するための方法が必要です。タスクを定義するには、単に書き、タスクは、あなたのコマンドを実行することができるように、Runnableをrun()メソッドを実装します。
パブリック クラス RunnableDemoは実装のRunnableは{ int型 I = 100 。 @オーバーライド 公共 のボイドの実行(){ しばらく(I - > 0 ){ Thread.yield(); } } }
タスクの実行()メソッドは、常にタスクの循環の形態であるがために)(ランで静的メソッドThread.yield()を呼び出し、されて続行することであったスケジューラスレッド CPUからのものであってもよい一部(Javaのスレッドメカニズムを別のスレッドに転送スレッド)勧告、それは述べて:「私は今、時間の別のタスクの実行期間に切り替えるための好機がある、最も重要な部分のライフサイクルを完了しました。
クラスはRunnableをエクスポートする場合、それは()メソッドを実行している必要がありますが、この方法はとても特別なものではありません - それは、内部スレッド機能を生成しません。郡の動作を実現するには、明示的にタスクがスレッドに添付しなければなりません。
2.Threadクラス
Runnableオブジェクトタスク伝統的な方法は、Threadコンストラクタにそれを提出することです:
パブリック 静的 ボイドメイン(文字列[]引数){ スレッドt = 新しいスレッド(新しいRunnableDemo()); t.start();
//他の方法 }
スレッドのコンストラクタはRunnableオブジェクトが必要です。必要な初期化を実行するためのスレッドのThreadオブジェクトのstart()メソッドを呼び出してから、この新しいスレッドでタスクを開始するために実行したRunnable()メソッドを呼び出します。start()メソッドは、実際のRunnable.run()への呼び出しを生成します。プログラムは、2つの方法、主他の内部()メソッドとRunnable.run()を実行するコードを実行する「同時に」は、他のスレッドを有するプログラムです。
3.エグゼキュータを使用します
アクチュエータ(Excutor)は並行プログラミングを簡素化する管理スレッド・オブジェクトを提供します。等価仲介。しかし、理由により非常にお勧めできません
4.戻り値はタスクから生成されます
Runnableを、タスクの独立した実装ですが、それは任意の値を返しません。あなたは、タスクが呼び出し可能インターフェースを実装する必要があります値を返すようにしたい場合。呼び出し可能な()メソッドの呼び出しから返された型パラメータを識別する一般的な値を有し、そしてExectorService.submit()メソッドの呼び出しでなければなりません。
パブリック クラスCallableDemo { 公共 静的 ボイドメイン(文字列[]引数){ ExecutorServiceのExecutorServiceの = 新しい ThreadPoolExecutor(5、10、60L、TimeUnit.SECONDS、新しい LinkedBlockingQueue <>(1 ))。 一覧 <今後の<string >>結果= 新しい ArrayListを<> (); 以下のために(int型、iは10 <; I = 0 iは++ ){ results.add(executorService.submit(新しいTaskWithResult(I))); } 以下のための(未来の<文字列> FS:結果){ 試み{ // 戻り値 のSystem.out.println(fs.get()); } キャッチ(例外e){ e.printStackTrace(); } 最後に{ executorService.shutdown(); } } } } クラス TaskWithResultは実装呼び出し可能<文字列> { プライベート int型のIDを、 TaskWithResult(int型のID){ この .ID = ID。 } @オーバーライド パブリック文字列コール(){ リターン「TaskWithResultの結果」+ ID。 } }
5.スリープ
タスクの動作に影響する簡単な方法は、対応するタスクの時間の実行を中断なる、()睡眠を呼び出すことです。
@Override 公共 ボイドラン(){ しようと{ TimeUnit.SECONDS.sleep( 3 )。 } キャッチ(InterruptedExceptionある電子){ e.printStackTrace(); } }
6.優先順位
スレッドスレッドの優先順位の重要性は、スケジューラ、最も優先度の高いスレッドが実行するようにする傾斜したスケジューラに渡されます。しかし、これは、(優先度の高い待機はデッドロックが発生することはありません)は、低優先度のスレッドが実行できないだけ低い周波数を実行するには、優先度の低いスレッドを意味するものではありません。ほとんどの時間、すべてのプログラムは、スレッドの優先度は通常間違いで操作しようと、デフォルトの優先度でなければなりません。
@Override 公共 ボイドラン(){ Thread.currentThread()setPriorityを(Thread.MIN_PRIORITY)。 。にThread.currentThread()getPriority(); }
最高でrunメソッドの優先順位を設定し、それは3つの一般的なレベルを使用するのが最適です。
Thread.MAX_PRIORITY
Thread.NORM_PRIORITY
Thread.MIN_PRIORITY
7.譲歩
仕事ができるようにいくつかの時間のためにやってたとき、他のスレッドは、CPUを使用しています。この時点で、あなたはヒントスケジュールスレッド化に(ちょうどヒントを、必ずしも採用する)Thread.yield()を使用することができます。
8.バックグラウンドスレッド
いわゆるバックグラウンドスレッドは、プログラムがバックグラウンドスレッドでユニバーサルサービスを提供し、実行していること、およびこのスレッドは、プログラムの不可欠な部分に属していません。すべての場合には非バックグラウンドスレッドが終了し、プログラムは終了します、そしてそれは、プロセス内のすべてのバックグラウンドスレッドを殺すでしょう。
バックグラウンドスレッドを設定します。
パブリック 静的 ボイドメイン(文字列[]引数){ Tスレッド = 新しい新しいスレッド(新しい新しいRunnableDemo()); // 提供スレッドに文章バックグラウンドスレッド (t.setDaemon trueに)。 t.start(); }
コーディングバリアント
非常に単純なケースでは、ああ、直接この代替の方法を継承スレッドを使用する場合があります:
パブリック クラス SimpleThradは拡張スレッド{ プライベート int型のカウントダウン= 5 ; / ** *それでもrunメソッドを実装する必要があります * / @オーバーライド 公共 ボイドラン(){ ながら、(真){ System.out.println(この); もし(--countDown == 0 ){ 返します。 } } } }
しかし、スレッド管理を実現ThreadPoolExecutorの使用を提唱したり促進しません。
10.用語
もし上記の各ケースから、あなたがスレッドを超える本当のコントロールを持っていないことがわかります。スレッドがタスクを駆動できるようにするには、タスクにアタッチスレッドでタスクを作成し、いくつかの方法インチ 自体は何もしないのJava Threadクラスでは、それだけで彼の運転の仕事を与え、それはあなたに別のタスクとスレッドのスレッド領域のより良い理解を行います。
11.スレッドに参加
スレッドは他のスレッドでjoin()メソッドを呼び出すことができ、効果は実行を継続する前に、第二のスレッドが終了するまである程度の時間を待つことです。スレッドがt.join()を呼び出した場合、tの終わりには、別のスレッドtで復元対象のスレッドを知ってまで、このスレッドは中断されます。
また、目的関数がパラメータの外時点で終了していないように、まだ返すように()メソッドへの参加、()プラス(ミリ秒単位)timeoutパラメータに参加することができます。参加()メソッドの呼び出しは、呼び出し元のスレッド上の()メソッドをinterrppt呼び出すために練習を中断し、のtry-catchを追加することができます。例えば、子供が理由の過程で、ここではありませんCycliBarrier良く参加するよりも。