Javaマルチスレッドの基本
Javaでは、マルチスレッドプログラミングを行うために、Thread
クラスやRunnable
インターフェースが提供されています。これらを利用することで、複数のスレッドを同時に実行することが可能になります。
スレッドの作成と実行
Javaで新しいスレッドを作成する基本的な方法は、Thread
クラスを継承するか、Runnable
インターフェースを実装することです。以下にそれぞれの方法を示します。
Threadクラスを継承:
class MyThread extends Thread {
public void run() {
// スレッドで実行したい処理
}
}
MyThread t = new MyThread();
t.start(); // スレッドの実行を開始
Runnableインターフェースを実装:
class MyRunnable implements Runnable {
public void run() {
// スレッドで実行したい処理
}
}
Thread t = new Thread(new MyRunnable());
t.start(); // スレッドの実行を開始
スレッドの終了
スレッドは、run()
メソッドが終了すると自動的に終了します。そのため、スレッドを終了させるためには、run()
メソッドが終了するようにプログラムを作成します。
以上がJavaのマルチスレッドプログラミングの基本的な部分です。次のセクションでは、スレッドに変数を渡す方法について詳しく説明します。
Threadに引数を渡す方法
Javaのスレッドに引数を渡す一般的な方法は、スレッドを作成するクラスにメンバ変数を追加し、その変数を通じて引数を渡すことです。以下に具体的なコード例を示します。
Threadクラスを継承した場合:
class MyThread extends Thread {
private int arg;
public MyThread(int arg) {
this.arg = arg;
}
public void run() {
// スレッドで実行したい処理
// ここでは arg を使用できます
}
}
MyThread t = new MyThread(10);
t.start(); // スレッドの実行を開始
Runnableインターフェースを実装した場合:
class MyRunnable implements Runnable {
private int arg;
public MyRunnable(int arg) {
this.arg = arg;
}
public void run() {
// スレッドで実行したい処理
// ここでは arg を使用できます
}
}
Thread t = new Thread(new MyRunnable(10));
t.start(); // スレッドの実行を開始
以上のように、スレッドに引数を渡すためには、スレッドを作成するクラスにメンバ変数を追加し、その変数を通じて引数を渡します。この方法を利用することで、スレッド内で必要なデータを柔軟に扱うことが可能になります。次のセクションでは、グローバル変数を使用する方法について詳しく説明します。
グローバル変数を使用する
Javaでは、複数のスレッド間でデータを共有するためにグローバル変数を使用することができます。ただし、マルチスレッド環境では、同時に複数のスレッドが同じ変数にアクセスする可能性があるため、データの整合性を保つためには注意が必要です。
以下に、グローバル変数を使用してスレッド間でデータを共有する例を示します。
class SharedData {
static int sharedVariable = 0;
}
class MyThread extends Thread {
public void run() {
// スレッドで実行したい処理
// ここでは sharedVariable を使用できます
SharedData.sharedVariable += 1;
}
}
MyThread t1 = new MyThread();
MyThread t2 = new MyThread();
t1.start(); // スレッドの実行を開始
t2.start(); // スレッドの実行を開始
この例では、SharedData
クラスのsharedVariable
という静的変数がグローバル変数として機能しています。この変数は、MyThread
クラスのrun
メソッド内から直接アクセスできます。
ただし、この方法には注意点があります。マルチスレッド環境では、複数のスレッドが同時にグローバル変数にアクセスする可能性があります。その結果、データの競合や不整合が発生する可能性があります。これを防ぐためには、Javaのsynchronized
キーワードやjava.util.concurrent
パッケージの機能を利用して、データの整合性を保つ必要があります。
次のセクションでは、スレッドを継承したクラスのメンバ変数を使用する方法について詳しく説明します。
Threadを継承したクラスのメンバ変数を使用する
Javaでは、Thread
クラスを継承したクラスのメンバ変数を使用して、スレッド間でデータを共有することができます。以下に具体的なコード例を示します。
class MyThread extends Thread {
private int arg;
public MyThread(int arg) {
this.arg = arg;
}
public void run() {
// スレッドで実行したい処理
// ここでは arg を使用できます
}
}
MyThread t1 = new MyThread(10);
MyThread t2 = new MyThread(20);
t1.start(); // スレッドの実行を開始
t2.start(); // スレッドの実行を開始
この例では、MyThread
クラスのarg
というメンバ変数が各スレッド間でデータを共有するための変数として機能しています。この変数は、MyThread
クラスのrun
メソッド内から直接アクセスできます。
ただし、この方法には注意点があります。マルチスレッド環境では、複数のスレッドが同時に同じオブジェクトのメンバ変数にアクセスする可能性があります。その結果、データの競合や不整合が発生する可能性があります。これを防ぐためには、Javaのsynchronized
キーワードやjava.util.concurrent
パッケージの機能を利用して、データの整合性を保つ必要があります。
次のセクションでは、スレッドにコールバック関数を渡す使用例について詳しく説明します。
使用例: Threadにコールバック関数を渡す
Javaでは、スレッドにコールバック関数を渡すことで、スレッドの実行結果を非同期に取得することが可能です。以下に具体的なコード例を示します。
まず、コールバック関数を定義するためのインターフェースを作成します。
interface Callback {
void call(int result);
}
次に、このコールバック関数を引数に取るスレッドを作成します。
class MyThread extends Thread {
private int arg;
private Callback callback;
public MyThread(int arg, Callback callback) {
this.arg = arg;
this.callback = callback;
}
public void run() {
// スレッドで実行したい処理
int result = arg * 2; // ここでは arg を2倍する処理を行っています
// 処理が終了したらコールバック関数を呼び出す
callback.call(result);
}
}
最後に、このスレッドを使用してみます。
Callback callback = new Callback() {
public void call(int result) {
System.out.println("Result: " + result);
}
};
MyThread t = new MyThread(10, callback);
t.start(); // スレッドの実行を開始
この例では、MyThread
クラスのrun
メソッド内で処理が終了したら、コールバック関数を呼び出して結果を非同期に返しています。この方法を利用することで、スレッドの実行結果を非同期に取得することが可能になります。ただし、マルチスレッド環境ではデータの競合や不整合が発生する可能性があるため、Javaのsynchronized
キーワードやjava.util.concurrent
パッケージの機能を利用して、データの整合性を保つ必要があります。このようにJavaでは、スレッドと変数の扱い方により、様々なマルチスレッドプログラミングが可能となります。それぞれの方法が適した場面を理解し、適切に利用していきましょう。