プログラミング 第15回

プログラミング 第15回
スレッド
[email protected]
プログラミング第15回
1
Thread
• プログラムを実行している主体
• 実行主体が複数あるプログラムはマルチ
スレッド
• 排他制御,同期などの問題がある。
• Threadをつくる方法
– Threadクラスをextendする
– Runnableインタフェースを実装する
プログラミング第15回
2
Threadをextendする方法
•
•
•
•
Threadのサブクラスとして定義する。
runメソッドを定義する。
インスタンスを作成する。
startメソッドを呼び出す。
– これで第2のスレッドが始まる。
– 第2のスレッドはrunメソッドを実行する。
– startメソッドを呼び出した側はメインのスレッド
として,実行を続ける。次の例ではmainメソッド。
プログラミング第15回
3
CountTenA.java (List 16-1, p.151)改
public class CountTenA extends Thread{
public static void main(String[] args){
CountTenA ct=new CountTenA();
ct.start();
for(int i=0; i<10; i++){
System.out.println("main:i="+i);
timeConsumer();
}
}
プログラミング第15回
4
CountTenA.java (2)
public void run(){
for(int i=0; i<10; i++){
timeConsumer();
System.out.println("run:i="+i);
}
}
プログラミング第15回
5
CountTenA.java (3)
private static void timeConsumer(){
for(int i=0; i<50; i++){
System.out.print("-");
}
System.out.println("");
}
}
プログラミング第15回
6
main:i=0
-------------------------------------------------main:i=1
-------------------------------------------------main:i=2
----------------------------------------------------------------------run:i=0
-------------------------------------------------run:i=1
-------------------------------------------------run:i=2
-------------------------------------------------------run:i=3
-------------------------------------------------run:i=4
-------------------------------------------------run:i=5
-------------------------------------------------run:i=6
-------------------------------------------------run:i=7
プログラミング第15回
実
行
例
7
---------------------------------main:i=3
-------------------------------------------------main:i=4
-------------------------------------------------main:i=5
-------------------------------------------------main:i=6
--------------------------------------------run:i=8
-------------------------------------------------run:i=9
-------------------------------main:i=7
-------------------------------------------------main:i=8
-------------------------------------------------main:i=9
-------------------------------------------------プログラミング第15回
実
行
例
8
実行イメージ
public class CountTenA extends Thread{
public static void main(String[] args){
CountTenA ct=new CountTenA();
ct.start();
for(int i=0; i<10; i++){
System.out.println("main:i="+i);}
}
public void run(){
for(int i=0; i<10; i++){
System.out.println("run:i="+i); }
}
}
プログラミング第15回
9
システムスレッドと新たなスレッド
:runtime system
CountTen
これはクラス
ct:CountTen
これはインスタンス
main
create
mainメソッドの実行
start
runメソッドの実行
プログラミング第15回
10
Runnableインタフェースを使う
• 自分自身はThreadクラスのサブクラスにな
らない。
• Threadクラスのインスタンスを生成し,自身
のrunメソッドを実行シナリオとして渡して,
実行を依頼する。
プログラミング第15回
11
CountTenB.java (List 16-2, p.156)改
public class CountTenB implements Runnable{
public static void main(String[] args){
CountTenB ct=new CountTenB();
Thread th=new Thread(ct);
th.start();
for(int i=0; i<10; i++){
System.out.println("main:i="+i);
timeConsumer();
}
}
プログラミング第15回
12
CountTenB.java (2)
public void run(){
for(int i=0; i<10; i++){
System.out.println("run:i="+i);
timeConsumer();
}
}
プログラミング第15回
13
CountTenB.java (3)
private static void timeConsumer(){
for(int i=0; i<50; i++){
System.out.print("-");
}
System.out.println("");
}
}
プログラミング第15回
14
システムスレッドと新たなスレッド
:runtime
ystem
CountTen ct:CountTen
クラス
インスタンス
th:Thread
インスタンス
main
create
mainメソッ
ドの実行
create
start
run
runメソッドの実行
プログラミング第15回
15
Runnable契約
• Thread のインスタンスは契約者乙
– コンストラクタThread(甲)により契約希望者の
登録を行う。
– start()メソッドが呼ばれたら,登録されている
甲に対して,run()の実行を開始する。
• Runnable実装者のインスタンスは契約者甲
– run()をしっかり定義する義務がある。
プログラミング第15回
16
スレッドの競合の例
•
•
•
•
2つのスレッドが同じフィールドに代入する。
現在残高valueをcurrentValueに保存
currentValueに引数moneyを加える
矛盾がないかチェックする
プログラミング第15回
17
public class BadBank{
private int value=0;
public void addMoney(int money){
int currentValue=value;
BadBank.java
(List 16-3,
p.161)
System.out.println(Thread.currentThread()
+"が addMoney に入りました。");
value+=money;
if(currentValue+money != value){
System.out.println(Thread.currentThread()
+"で矛盾が発生しました!");
System.exit(-1);}
System.out.println(Thread.currentThread()
+"がaddMoneyから出ました。");
}
}
プログラミング第15回
18
BadBankTest.java (List 16-4,
p.161)
public class BadBankTest extends Thread{
BadBank bank;
public BadBankTest(BadBank bank){
this.bank=bank;
}
プログラミング第15回
19
public void run(){
BadBankTest.java (2)
while(true){
bank.addMoney(100);
bank.addMoney(-100);
}
}
public static void main(String[] args){
BadBank bank=new BadBank();
new BadBankTest(bank).start();
new BadBankTest(bank).start();
}
}
プログラミング第15回
20
実行例
.......
Thread[Thread-1,5,main]がaddMoneyから出ました。
Thread[Thread-1,5,main]が addMoney に入りました。
Thread[Thread-1,5,main]がaddMoneyから出ました。
Thread[Thread-1,5,main]が addMoney に入りました。
Thread[Thread-1,5,main]がaddMoneyから出ました。
Thread[Thread-0,5,main]で矛盾が発生しました!
プログラミング第15回
21