Javaスレッドチュートリアルタイプの質問
-
03-07-2019 - |
質問
Java Threading and Concurrencyの世界に関しては、かなり単純です。現在、学ぼうとしています。並行性がどのように機能するかを理解するために、簡単な例を作成しました。
ここに私のコードがあります:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ThreadedService {
private ExecutorService exec;
/**
* @param delegate
* @param poolSize
*/
public ThreadedService(int poolSize) {
if (poolSize < 1) {
this.exec = Executors.newCachedThreadPool();
} else {
this.exec = Executors.newFixedThreadPool(poolSize);
}
}
public void add(final String str) {
exec.execute(new Runnable() {
public void run() {
System.out.println(str);
}
});
}
public static void main(String args[]) {
ThreadedService t = new ThreadedService(25);
for (int i = 0; i < 100; i++) {
t.add("ADD: " + i);
}
}
}
コードに0から99までの数字を順番に出力させるにはどうすればよいですか?
解決
0から99までの数字を順番に印刷することは同時並行の問題ではなく、順番が乱れて印刷されないようにスレッドを同期する必要があります。
Java並行性レッスンをご覧になることをお勧めしますJavaでの並行性のアイデアを得るために。
他のヒント
スレッドの考え方は、物事を順番に行うことではありません。
調整するには共有状態が必要です。この例では、外部クラスにインスタンスフィールドを追加すると機能します。追加からパラメーターを削除します。ロックオブジェクトとカウンターを追加します。ロックをつかみ、数字をインクリメント印刷し、数字をインクリメントし、数字を放します。
問題の最も簡単な解決策は、1のThreadPoolサイズを使用することです。ただし、これは実際にスレッドを使用して解決するような種類の問題ではありません。
展開するには、executorを次のように作成します:
this.exec = Executors.newSingleThreadExecutor();
その後、スレッドはすべて、実行のために送信された順序でスケジュールおよび実行されます。これが論理的なことであるいくつかのシナリオがありますが、ほとんどの場合、スレッドはこの問題を解決するために使用する間違ったツールです。
この種のことは、タスクを別のスレッドで実行する必要がある場合に実行するのが理にかなっています-おそらく実行に時間がかかり、GUIスレッドをブロックしたくないでしょうが-送信されたタスクを同時に実行する必要があるか、または望ましくない。
問題は、定義上、スレッドに適していません。スレッドは独立して実行され、実際にどのスレッドが最初に実行されるかを予測する方法はありません。
コードを連続して実行するように変更する場合は、add to:を変更します。
public void add(final String str) {
System.out.println(str);
}
スレッドを使用しておらず(少なくとも自分のスレッドではありません)、すべてが順番に行われます。