「SJC-P 並行性」の版間の差分
ナビゲーションに移動
検索に移動
1行目: | 1行目: | ||
− | ==SJC-P 並行性== | + | ==[[SJC-P 並行性]]== |
===スレッド=== | ===スレッド=== | ||
*各スレッドには優先順位 | *各スレッドには優先順位 | ||
*新しい実行のスレッドを作成するには 2 通りの方法 | *新しい実行のスレッドを作成するには 2 通りの方法 | ||
**クラスを Thread のサブクラスであると宣言 | **クラスを Thread のサブクラスであると宣言 | ||
− | ** | + | **[[R]]unnable インタフェースを実装するクラスを宣言 |
− | * | + | *[[R]]unnable実装クラスの、run()メソッドを直接呼ばない(単なるメソッドの呼び出しとなり、スレッドは開始されない)。Thread.start()を利用する。 |
関連メソッド | 関連メソッド | ||
67行目: | 67行目: | ||
import java.awt.BorderLayout; | import java.awt.BorderLayout; | ||
− | import javax.swing.JFrame; | + | import javax.swing.[[JFrame]]; |
import javax.swing.JTextField; | import javax.swing.JTextField; | ||
− | import javax.swing. | + | import javax.swing.[[Swing]]Utilities; |
@SuppressWarnings("serial") | @SuppressWarnings("serial") | ||
− | public class ThreadTest extends JFrame { | + | public class ThreadTest extends [[JFrame]] { |
private JTextField txt1; | private JTextField txt1; | ||
private JTextField txt2; | private JTextField txt2; | ||
public ThreadTest() { | public ThreadTest() { | ||
− | this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); | + | this.setDefaultCloseOperation([[JFrame]].EXIT_ON_CLOSE); |
txt1 = new JTextField(); | txt1 = new JTextField(); | ||
txt2 = new JTextField(); | txt2 = new JTextField(); | ||
− | this.getContentPane().add(txt1, BorderLayout. | + | this.getContentPane().add(txt1, BorderLayout.CENTE[[R]]); |
this.getContentPane().add(txt2, BorderLayout.SOUTH); | this.getContentPane().add(txt2, BorderLayout.SOUTH); | ||
// 非同期でテキストフィールドの内容をカウントアップするスレッドを作成 | // 非同期でテキストフィールドの内容をカウントアップするスレッドを作成 | ||
Thread t = new Thread( | Thread t = new Thread( | ||
− | // | + | // Threadコンストラクタの引数に[[R]]unnableインターフェースの実装クラスを渡す |
− | new | + | new [[R]]unnable() { |
public void run() { | public void run() { | ||
int i = 0; | int i = 0; | ||
103行目: | 103行目: | ||
} | } | ||
public static void main(String[] args) throws Exception { | public static void main(String[] args) throws Exception { | ||
− | + | [[Swing]]Utilities.invokeAndWait( | |
− | new | + | new [[R]]unnable() { |
public void run() { | public void run() { | ||
new ThreadTest(); | new ThreadTest(); | ||
114行目: | 114行目: | ||
===標準入力を待つスレッドと、入力された値をエコーするスレッドを、wait,notifyAll で協調動作させる。=== | ===標準入力を待つスレッドと、入力された値をエコーするスレッドを、wait,notifyAll で協調動作させる。=== | ||
− | import java.io. | + | import java.io.Buffered[[R]]eader; |
import java.io.IOException; | import java.io.IOException; | ||
− | import java.io. | + | import java.io.InputStream[[R]]eader; |
import java.util.LinkedList; | import java.util.LinkedList; | ||
import java.util.Queue; | import java.util.Queue; | ||
129行目: | 129行目: | ||
} | } | ||
− | private class InputProcess implements | + | private class InputProcess implements [[R]]unnable { |
public void run() { | public void run() { | ||
// 共有オブジェクト(モニター)を同期指定 | // 共有オブジェクト(モニター)を同期指定 | ||
synchronized (queu) { | synchronized (queu) { | ||
try { | try { | ||
− | + | Buffered[[R]]eader reader = new Buffered[[R]]eader(new InputStream[[R]]eader(System.in)); | |
System.out.print("input message >"); | System.out.print("input message >"); | ||
String line = null; | String line = null; | ||
149行目: | 149行目: | ||
} | } | ||
} | } | ||
− | private class OutputProcess implements | + | private class OutputProcess implements [[R]]unnable { |
public void run() { | public void run() { | ||
synchronized (queu) { | synchronized (queu) { | ||
175行目: | 175行目: | ||
new Thread(ct1.new T2()).start(); | new Thread(ct1.new T2()).start(); | ||
} | } | ||
− | private class T1 implements | + | private class T1 implements [[R]]unnable { |
public void run() { | public void run() { | ||
for (int i=0;i<5;i++) { | for (int i=0;i<5;i++) { | ||
// こういうロックも取得できる | // こういうロックも取得できる | ||
− | // | + | // 標準出力への割り込みをブロックし、STA[[R]]T-ENDが対になるように制御 |
synchronized (System.out) { | synchronized (System.out) { | ||
− | System.out.println("T1(" + i + ") | + | System.out.println("T1(" + i + ") STA[[R]]T"); |
try { Thread.sleep(1000); } | try { Thread.sleep(1000); } | ||
catch (InterruptedException e){ e.printStackTrace(); } | catch (InterruptedException e){ e.printStackTrace(); } | ||
190行目: | 190行目: | ||
} | } | ||
} | } | ||
− | private class T2 implements | + | private class T2 implements [[R]]unnable { |
public void run() { | public void run() { | ||
for (int i=0;i<5;i++) { | for (int i=0;i<5;i++) { | ||
synchronized (System.out) { | synchronized (System.out) { | ||
− | System.out.println("T2(" + i + ") | + | System.out.println("T2(" + i + ") STA[[R]]T"); |
try { Thread.sleep(500); } | try { Thread.sleep(500); } | ||
catch (InterruptedException e){ e.printStackTrace(); } | catch (InterruptedException e){ e.printStackTrace(); } | ||
205行目: | 205行目: | ||
'''結果''' | '''結果''' | ||
− | T1(0) | + | T1(0) STA[[R]]T |
T1(0) END | T1(0) END | ||
− | T2(0) | + | T2(0) STA[[R]]T |
T2(0) END | T2(0) END | ||
− | T1(1) | + | T1(1) STA[[R]]T |
T1(1) END | T1(1) END | ||
− | T2(1) | + | T2(1) STA[[R]]T |
T2(1) END | T2(1) END | ||
− | T1(2) | + | T1(2) STA[[R]]T |
T1(2) END | T1(2) END | ||
− | T2(2) | + | T2(2) STA[[R]]T |
T2(2) END | T2(2) END | ||
− | T1(3) | + | T1(3) STA[[R]]T |
T1(3) END | T1(3) END | ||
: | : | ||
− | synchronized | + | synchronized がないと、T1、T2のSTA[[R]]T-ENDの間に割り込こみが起こる。 |
2020年2月16日 (日) 04:32時点における最新版
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 矢木浩人