マルチコアシナリオでのJavaプログラムのコーディングのヒント[非公開]
-
03-07-2019 - |
質問
マルチコアとJavaについては大騒ぎしているようです。 Javaサポートは十分ではないと言う人もいます、それは間違いなく楽しみにしています。 多数 技術を使用して、並行プログラムのパフォーマンスを向上させます。
マルチコアシナリオでのプログラミングに関するヒントやアドバイスをいただければ幸いです。
解決
新しいJava並行性機能を調べます( java.util.concurrent
パッケージ)。これはJava 5に追加されました。通常のThread
sよりも高レベルの機能を提供するため、エラーが発生しにくくなります。並行アプリケーションを作成します。
これまでは、 ExecutorService
。これにより、を生成できます。スレッドプール。新しいタスクを Runnable
sまたは Callable
s(実行後に Future
s)、実際のスレッドコードはsubmit
によって処理されます。
たとえば、2つのスレッドのスレッドプールを使用して計算を実行し、結果を取得するのは次のように簡単です。
ExecutorService es = Executors.newFixedThreadPool(2);
Future f1 = es.submit(new Callable<Integer>() {
public Integer call()
{
// Do some processing...
return someInteger;
}
});
Future f2 = es.submit(new Callable<Integer>() {
public Integer call()
{
// Do some processing...
return someInteger;
}
});
Integer firstInteger = f1.get();
Integer secondInteger = f2.get();
上記の(テストされていない)コードでは、get
sと f2
f1
以降に<を使用して=> sで結果を取得します。
キャッチは、一度の "noreferrer"> <=> メソッドが呼び出されます。処理が完了していない場合、<=>の結果を取得できるまでプログラムは停止します。したがって、この例では、<=>の結果が<=>の前に利用可能であっても、プログラムは<=>の結果が利用可能になるまで待機します。
資料を読むという観点から、まもなく購入する書籍のリストには、ブライアンゲッツによる Java同時実行の実践があります。これは、Javaの同時実行性が発生したときに頻繁に発生します。
Java 5ドキュメントの同時実行ユーティリティページさらに情報があります。
他のヒント
最良のヒントは、同期を正しく行うことです
これはやや明白に思えるかもしれませんが、特に Javaメモリモデルを理解することが重要です。特に volatile フィールドと final フィールドの動作、同期がミューテックス メモリバリアそして、新しいjava.util.concurrent
構造も同様に
常に良いヒント-クラスの大部分が不変である場合、不変性により、多くのまたは少数の懸念場所からロックを心配する必要がなくなるため、すべてが非常に簡単になります。
近日公開予定の fork-joinフレームワークをご覧ください。 。開発者はfork-joinフレームワークを使用して、マルチコアアーキテクチャ上できめ細かい並列処理を実現できます。
また、マルチコア並列プログラミングを容易にすることを主張する Clojure などのJVMベースの言語をチェックアウトすることもできます。
並行性に対するJava独自の共有メモリアプローチの代替として、を調べることもできます。 Java上でScala を使用するアクターベースの同時実行。これにより、並行プログラミングのより簡単なモデルが提供されます。
ブライアンゲッツの講演 Devoxx 2008の並行処理から並列処理へ。そこには多くのヒントはありませんが、Javaの並行性がどこに向かっているのかがわかります。
Javaの Skandium などの並列パターンライブラリを使用してみてください。必要な並列処理パターンを選択し、不足しているフックを埋めるだけです。
Skandiumでサポートされているパターンの一部は次のとおりです。
- マスタースレーブ:
Farm<P,R>(nested);
- パイプライン: `Pipe(stage1、stage2);
- 反復の場合:
For<P,R>(nested, i);
- 条件付き反復:
While<P,R>(nested, condition);
- 条件分岐:
If<P,R>(condition, trueCase, falseCase);
- Map-reduce:
Map<P,R>(split, nested, merge);
- 異なるコードパスを使用したMap-reduce:
Fork<P,R>(split, nested, merge);
- 再帰的な分割と征服:
DaC<P,R>(condition, split, nested, merge);
すべてのパターンをネストして結合することができるため、農場を分割して征服するなどできます。
実用的なヒントが記載された最高の本は、実践におけるJava同時実行性です。 Javaにはさまざまなライブラリに多くの隠されたスレッドがあります(サーブレットと同じように頭に浮かぶので)。
私のヒント:Javaメモリモデルを理解する(JDK 5以降)。ほとんどの人は、同期、揮発性、および最終が通常のマルチスレッドスコープを超える追加の意味を持つことを知りません。
Javaは、マルチCPUおよびマルチコアに適しています。適切にプログラミングし、ある程度の頭脳を投資すれば、多くの同期などを含む8コアを活用するための高度な同時サーバーシステムが得られます。 JDK6はJDK5よりも優れており、以下のすべてがマルチCPUマシンでうまくいきません。