プログラミング 第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
© Copyright 2024 ExpyDoc