- 追加された行はこのように表示されます。
- 削除された行は
このように表示されます。
!!!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() メソッドを呼び出すまで、現在のスレッドを待機
::例
{{ref_image cup.jpg}}
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の間に割り込こみが起こる。