Java スレッド
スレッドを使用すると、複数のことを同時に実行することで、プログラムをより効率的に操作できます。
スレッドを使用すると、メインプログラムを中断することなくバックグラウンドで複雑なタスクを実行できます。
スレッドの作成
スレッドを作成する方法は2つあります。
Thread
クラスを拡張し、そのrun()
メソッドをオーバーライドすることで作成可能です。
拡張構文
public class Main extends Thread {
public void run() {
System.out.println("This code is running in a thread");
}
}
スレッドを作成する別の方法は、Runnable
インターフェースを実装します。
実装構文
public class Main implements Runnable {
public void run() {
System.out.println("This code is running in a thread");
}
}
実行中のスレッド
クラスがThread
クラス継承している場合、そのクラスのインスタンスを作成し、start()
メソッドを呼び出すことで、スレッドを実行できます。
拡張例
public class Main extends Thread {
public static void main(String[] args) {
Main thread = new Main();
thread.start();
System.out.println("This code is outside of the thread");
}
public void run() {
System.out.println("This code is running in a thread");
}
}
自分で試してみる»
クラスがRunnable
インターフェイス実装している場合、Thread
オブジェクトのコンストラクタにクラスのインスタンスを私、Thread
のstart
メソッドを呼び出すことで実行できる。
実装例
public class Main implements Runnable {
public static void main(String[] args) {
Main obj = new Main();
Thread thread = new Thread(obj);
thread.start();
System.out.println("This code is outside of the thread");
}
public void run() {
System.out.println("This code is running in a thread");
}
}
自分で試してみる»
Threadsの「拡張」と「実装」の違い
主な違いは、クラスがThreadクラスを継承している場合、他のクラスを継承することはできませんが、Runnableインターフェースを実装することにより、次のように別のクラスからも拡張できることです。MyClass extends OtherClass implements Runnable
並行処理の問題
スレッドはプログラムの他の部分と同時に実行されるため、コードがどの順序で実行されるかを知る方法はありません。スレッドとメインプログラムが同じ変数の読み取りと書き込みを行っている場合、値は予測できません。この結果を生じる問題を、並行性の問題と呼ばれます。
例
変数の値が予測不可能なコード
public class Main extends Thread {
public static int amount = 0;
public static void main(String[] args) {
Main thread = new Main();
thread.start();
System.out.println(amount);
amount++;
System.out.println(amount);
}
public void run() {
amount++;
}
}
自分で試してみる»
並行性の問題を回避するには、スレッド間で共有する属性をできるだけ少なくすることをお勧めします。属性を共有する必要がある場合、スレッドが変更できる属性を使用する前に、スレッドのisAlive()
メソッドを使用してスレッドの実行を終了したかどうかをチェックすることが解決策の1つです。
例
使用isAlive()
同時実行の問題を防ぐには:
public class Main extends Thread {
public static int amount = 0;
public static void main(String[] args) {
Main thread = new Main();
thread.start();
// Wait for the thread to finish
while(thread.isAlive()) {
System.out.println("Waiting...");
}
// Update amount and print its value
System.out.println("Main: " + amount);
amount++;
System.out.println("Main: " + amount);
}
public void run() {
amount++;
}
}
自分で試してみる»