SJC-P 並行性
ナビゲーションに移動
検索に移動
SJC-P 並行性
スレッド
- 各スレッドには優先順位
- 新しい実行のスレッドを作成するには 2 通りの方法
- クラスを Thread のサブクラスであると宣言
- Runnable インタフェースを実装するクラスを宣言
- Runnable実装クラスの、run()メソッドを直接呼ばない(単なるメソッドの呼び出しとなり、スレッドは開始されない)。Thread.start()を利用する。
関連メソッド
method | 内容 |
---|---|
getPriority() | 優先順位を返す |
setPriority(int newPriority) | 優先順位を変更 |
getState() | 状態を返す |
interrupt() | このスレッドに割り込み |
interrupted() | 現在のスレッドが割り込まれているかどうか |
isInterrupted() | このスレッドが割り込まれているどうか |
isAlive() | このスレッドが生存しているかどうか |
isDaemon() | このスレッドがデーモンスレッドであるかどうか |
setDaemon(boolean on) | デーモンスレッドまたはユーザースレッドとしてマーク |
join() | このスレッドが終了するのを待機 |
sleep(long millis) | 現在実行中のスレッドを、指定されたミリ秒数の間、スリープ |
start() | スレッドの実行を開始 |
yield() | 現在実行中のスレッドオブジェクトを一時的に休止させ、ほかのスレッドが実行できるように |
notify() | このオブジェクトのモニターで待機中のスレッドを 1 つ再開 |
notifyAll() | このオブジェクトのモニターで待機中のすべてのスレッドを再開 |
wait() | ほかのスレッドがこのオブジェクトの notify() メソッドまたは notifyAll() メソッドを呼び出すまで、現在のスレッドを待機 |
例
import java.awt.BorderLayout; import javax.swing.JFrame; import javax.swing.JTextField; import javax.swing.SwingUtilities; @SuppressWarnings("serial") public class ThreadTest extends JFrame { private JTextField txt1; private JTextField txt2; public ThreadTest() { this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); txt1 = new JTextField(); txt2 = new JTextField(); this.getContentPane().add(txt1, BorderLayout.CENTER); this.getContentPane().add(txt2, BorderLayout.SOUTH); // 非同期でテキストフィールドの内容をカウントアップするスレッドを作成 Thread t = new Thread( // Threadコンストラクタの引数にRunnableインターフェースの実装クラスを渡す new Runnable() { public void run() { int i = 0; while (true) { txt2.setText(String.valueOf(i++)); try { Thread.sleep(500); } catch (InterruptedException e) {} } } } ); // 開始(Thred.start()を呼ぶ) t.start(); this.pack(); this.setVisible(true); } public static void main(String[] args) throws Exception { SwingUtilities.invokeAndWait( new Runnable() { public void run() { new ThreadTest(); } } ); } }
標準入力を待つスレッドと、入力された値をエコーするスレッドを、wait,notifyAll で協調動作させる。
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.LinkedList; import java.util.Queue; public class ConcurrentTest4 { Queue<String> queu = new LinkedList<String>(); public static void main(String[] args) { ConcurrentTest4 me = new ConcurrentTest4(); new Thread(me.new InputProcess()).start(); new Thread(me.new OutputProcess()).start(); } private class InputProcess implements Runnable { public void run() { // 共有オブジェクト(モニター)を同期指定 synchronized (queu) { try { BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); System.out.print("input message >"); String line = null; while ((line = reader.readLine()) != null) { queu.offer(line); // キューに挿入 // 準備が終わったので、OutputProcessに通知し、自身はwaitする queu.notifyAll(); System.out.println("[in]waiting..."); queu.wait(); // waitを呼び出すとき、現在のスレッドは、このオブジェクトモニターのオーナでなければならない。 } } catch (IOException ioe) { ioe.printStackTrace(); } catch (InterruptedException ipe) { ipe.printStackTrace(); } } } } private class OutputProcess implements Runnable { public void run() { synchronized (queu) { while (true) { try { if (queu.size() > 0) { System.out.println("echo >" + queu.poll()); // 処理が終わったので、InputProcess に通知し、自身はwait queu.notifyAll(); } System.out.println("[out]waiting..."); queu.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } } } }
public class ConcurrentTest1 { public static void main(String[] args) { ConcurrentTest1 ct1 = new ConcurrentTest1(); new Thread(ct1.new T1()).start(); new Thread(ct1.new T2()).start(); } private class T1 implements Runnable { public void run() { for (int i=0;i<5;i++) { // こういうロックも取得できる // 標準出力への割り込みをブロックし、START-ENDが対になるように制御 synchronized (System.out) { System.out.println("T1(" + i + ") START"); try { Thread.sleep(1000); } catch (InterruptedException e){ e.printStackTrace(); } System.out.println("T1(" + i + ") END"); } } } } private class T2 implements Runnable { public void run() { for (int i=0;i<5;i++) { synchronized (System.out) { System.out.println("T2(" + i + ") START"); try { Thread.sleep(500); } catch (InterruptedException e){ e.printStackTrace(); } System.out.println("T2(" + i + ") END"); } } } } }
結果
T1(0) START T1(0) END T2(0) START T2(0) END T1(1) START T1(1) END T2(1) START T2(1) END T1(2) START T1(2) END T2(2) START T2(2) END T1(3) START T1(3) END :
synchronized がないと、T1、T2のSTART-ENDの間に割り込こみが起こる。
© 2006 矢木浩人