マルチスレッド処理 (I) Multithreading • • • • • • • マルチスレッド(multithread)とは何か どうしてマルチスレッドが必要ですか スレッドのライフサイクル スレッドの定義とメソッド マルチスレッドな例 スレッドの同期 スレッドの同期の例 スレッド(thread): アプリケーションから一部の機能をスレッドとして実行します。 スレッドはプログラムに一部の機能を実行している主体です。 マルチスレッド: 同時に複数のスレッドが存在する。それらのスレッド が並行して動作するのは,マルチスレッド処理機能です。これはJava 言語の特徴の一つです。 Javaでは、スレッドというのは、一つのオブジェクトです。 クラススレッドのコンストラクタ クラススレッドのインスタンス public Thread() Thread thread1, thread2; public Thread(String threadName) thread1 = new Thread(); …… thread2 = new Thread(“student”); java.lang.Object | +--java.lang.Thread スレッドのライフサイクル (Life cycle of a thread) スレッド状態 (スレッドのライフサイクル):誕生=>レディ=>実行=>死亡。 誕生 待機 休眠 中断 ブロック start 実行可能 yield dispatch 実行 待機 休眠 中断 ブロック resume スリープ時間が経過 stop 死亡 クラスThreadのメソッド 実行結果 ex2 (The Thread methods) public void start() IllegalThreadStateException runメソッドを起動し、期待された仕事を行う。 public final void stop() SecurityException ThreadDeathオブジェクトを送出することによってスレッドを停止させる。 public final void suspend() スレッドの実行を中断される。 public final void resume() 中断されたスレッドを再開させる。 public static void sleep(long millis) InterruptedException スレッドを眠らせる。 public final void wait() ターゲットオブジェクトを待つためにwaitメソッドを呼び出し、待機状態に入る。 public final void notify() 待ち行列の先頭にあるスレッドが実行可能状態に移る。 IllegalMonitorStateException public final void notifyAll() 待ち行列にあるスレッドがすべて実行可能状態に移る。 public final void setName(String name) スレッドの名前を設定する。 public final String getName() スレッドの名前を返す。 public static Thread currentThread() カレントスレッドへの参照を返す。 public final boolean isAlive() スレッドが生きているかを判断する。 SecurityException public void run() スレッドstart()を呼び出すとき、 run()メソッドを起動します。 スレッドクラスの定義 Definition of a thread class キーワード class スレッドクラス名前 thread_name …… キーワード キーワード extends Thread { // 必要な変数とコンストラクタの宣言 public void run(){ 必ずrun()メソッドの 再定義が必要です。 …… } } 実行結果:L71 スレッド CountTenThreadの 定義 スレッドcttのrunメ ソッドの実行開始 class CountTenThread extends Thread { public void run() { for (int i = 0; i < 10; i++) { System.out.println("run:i = " + i);}} } public class ThreadTest { public static void main(String[] args) { CountTenThread ctt = new CountTenThread(); ctt.start(); for (int i = 0; i < 10; i++) { System.out.println("main:i = " + i);}} } CountTenThreadのスレッド。 runメソッドが終ると消滅。 mainのスレッド 簡単な例 A simple example クラスThreadから導出したサブクラスのスレッドSleepPrintThreadを4つ生成し、 その中でThreadメソッドsleepを呼び出します。これらのスレッドは0~5秒間(乱 数で決定)眠ったあと、それぞれの名前を表示します。 class SleepPrintThread extends Thread { int sleepTime; public PrintThread() { // 0~5秒間スリープ sleepTime = (int) ( Math.random() * 5000 ); System.out.println( "Name: " + getName() + "; sleep: " + sleepTime ); } public void run() スレッドSleepPrintThreadの { sleepメソッドの実行開始 try { Thread.sleep( sleepTime ); } catch ( InterruptedException exception ) { System.err.println( exception.toString() ); } System.out.println( getName() ); } } スレッドSleepPrintThreadの getNameメソッドを呼び出す public class PrintTest { public static void main( String args[] ) { SleepPrintThread thread1. thread2; SleepPrintThread thread3, thread4; thread1 = new SleepPrintThread(); thread2 = new SleepPrintThread(); thread3 = new SleepPrintThread(); thread4 = new SleepPrintThread(); thread1.start(); thread2.start(); thread3.start(); thread4.start(); } 四つSleepPrintThread オブジェクトを生成する スレッド名前とスリープ 時間を出力する runメソッドが実行されると、 スレッド名前を出力する } 実行結果:L72 スレッドの例 An example of multithreading: Producer/Consumer Without thread synchronization Producer sets i Consumer gets j IntegerStore IntegerStoreの最大値は一つ整数です class Producer extends Thread { private IntegerStore pStore; public Producer( IntegerStore iS ) { pStore = iS; } public void run() { for ( int count = 0; count < 10; count++ ) { try { Thread.sleep( (int) ( Math.random() * 3000 ) ); } catch( InterruptedException e ) { System.err.println( e.toString() ); } pStore.setSharedInt( count ); System.out.println( "Producer set sharedInt to " + count ); } pStore.setMoreData( false ); } } 実行結果:L73 class Consumer extends Thread { private IntegerStore cStore; public ConsumeInteger( IntegerStore iS) { cStore = iS; } public void run() { int val; while ( cStore.hasMoreData() ) { try { Thread.sleep( (int) ( Math.random() * 3000 ) ); } catch( InterruptedException e ) { System.err.println( e.toString() ); } val = cStore.getSharedInt(); System.out.println( "Consumer retrieved " + val ); } } } class IntegerStore { public class SharedStore { private int sharedInt = -1; private boolean moreData = true; public static void main( String args[] ) public void setSharedInt( int val ) { sharedInt = val; } { IntegerStore is = new IntegerStore(); public int getSharedInt() { return sharedInt; } Producer p = new Producer(is ); public void setMoreData( boolean b ) { moreData = b; } Consumeer c = new Consumer( is ); public boolean hasMoreData() { return moreData; } p.start(); c.start(); }} } スレッドの同期 Thread Synchronization どうしていつかスレッドの同期が必要か? オブジェクトでは、一度に1個のスレッドしか同期メソッドを実行することができない時。 どうやってマルチスレッド同期することができるか? 同期メソッドとは何か? =>同期メソッドはメソッドをsynchronizedで宣言することです。 モニタオブジェクトとは何か?=>同期メソッドを持つオブジェクトはモニタオブジェクトと言う。 モニタオブジェクトに複数の同期メソッドがある場合も、同時には1個の同期メソッドしか実行されません。 同期メソッドを呼び出そうとするほかのスレッドは全て待ったされます。 実行中の同期メソッドが終了するとそのオブジェクトのロックが解除され、 モニタは同時メソッドを呼び出そうと待っているスレッドの中から最も優先度の高いものを実行します。 public final void wait() public final void notify() public final void notifyAll() Waitメソッドの呼び出しには、待機状 態を終わらせるためのnotifyまたは notifyAllメソッドの呼び出しが必ず 対応していなければいけません。 同期メソッドを実行してい るスレッドがそれ以上進 めないと判断した時は、 自発的にwaitメソッドを呼 び出す。 マルチスレッド化したプログラムを正常に 動かすにはスレッドの同期が不可欠です が、スレッドが待たされるためにプログラ ムのパフォーマンスが悪くなることがあり ます。けれども、しょうがないです。 スレッドの例 An example of multithreading: Producer/Consumer With thread synchronization Producer sets i Consumer gets j (i=j) IntegerStore IntegerStoreの最大値は一つ整数です class IntegerStore { private int sharedInt = -1; private boolean moreData = true; public void setSharedInt( int val ) { sharedInt = val; } public int getSharedInt() { return sharedInt; } public void setMoreData( boolean b ) { moreData = b; } public boolean hasMoreData() { return moreData; } } public class SharedStore { public static void main( String args[] ) { IntegerStore is = new IntegerStore(); Producer p = new Producer(is ); Consumeer c = new Consumer( is ); p.start(); c.start(); } } 実行結果:L74 class IntegerStore { private int sharedInt = -1; private boolean moreData = true; private boolean writeable = true; public synchronized void setSharedInt( int val ) { while(!writeable) { try { wait(); } catch (InterruptedException e){ System.err.println("Exception: " + e.toString()); } } sharedInt = val; writeable = false; notify(); } public synchronized int getSharedInt() { while (writeable){ try{ wait(); } catch(InterruptedException e){ System.err.println("Exception: " + e.toString()); } } writeable = true; notify(); return sharedInt; } public void setMoreData( boolean b ) { moreData = b; } public boolean hasMoreData() { return moreData; } } 課題 (Exercise) 実行結果 ex1 実行結果 ex2 1.以下のような、つぎの2つのスレッドクラスを定義せよ。 SquareTheread class: 3.1 以下のようなMotherThread classとBabyThread classを定義せよ。 MotherThread class: スレッドの名前をセットするコンストラクタ スレッドの名前をセットするコンストラクタ for i=1~9, for i=0~9, iの値とスレッドの名前、i*iの値を0~1000ミリ秒のスリープタイム でプリントする。 スレッドの名前、iのfeeding sequenceをプリントする。 BabyTread class: スレッドの名前と文字列"is done!"をプリントする。 CubeThread class: スレッドの名前をセットするコンストラクタ for i=0~9, スレッドの名前をセットするコンストラクタ スレッドの名前、iのeating sequenceをプリントする。 for i=1~9 3.2 MotherThreadスレッドとBabyThreadスレッドを生成してスタートさせる iの値とスレッドの名前、i*i*iの値を0~1000ミリ秒のスリープタイム でプリントする。 Javaアプリケーションプログラムを記述せよ。 3.3 mother feedingとbaby eatingに同期するsynchronized feed(int value) スレッドの名前と文字列“is done!”をプリントする。 メソッドとsynchronized eat(int value)メソッドを持つMouthThreadクラス を定義せよ。 2.SquareThreadスレッドとCubeThreadスレッドを生成してスタートさせる Javaアプリケーションプログラムを記述せよ。 3.motherがa sequence of foodsを与えると仮定せよ。i=0~9で、babyは以下に従う。 Month feeds Baby’s mouth Mother takes 0~1000 to feed Baby eats Baby takes 0~1000 to eat mouthの最大値は一つfeed class Mouth{ public synchronized void feed( int val ) {……} public synchronized int eat() {……} public void feedMore( boolean b ) {……} public boolean hasFood() { …… } } class MotherThread extends Thread { //constructor, run() } class BabyThread extends Thread { //constructor, run()} public class MotherBaby { // main() } //application program 課題 (Exercise) 実行結果 ex1 1. Define two your own thread classes that do the following work. SquareThread class: a constructor to set the thread’s name, for i = 1 ~ 9, print value i, name of the thread, square value i*i sleep 0~1000 milliseconds print name of the thread and the string “ is done!” CubeThread class: a constructor to set the thread’s name, for i = 1 ~ 9, print value i, name of the thread, cube value i*i*i sleep 0~1000 milliseconds print name of the thread and the string “ is done!” 2. Write a Java application program that creates a SquareThread thread and CubeThread thread and starts these two threads. 3. Suppose that a mother feeds a sequence of foods, 3.1 Define MotherThread class and BabyThread class that do the following work MotherThread class: a construct to set the thread’s name, for i = 0 ~ 9, print name of the thread, feeding sequence number I sleep 0~1000 milliseconds BabyThread class: a construct to set the thread’s name, for i = 0 ~ 9, print name of the thread, eating sequence number I sleep 0~1000 milliseconds 3.2 Write a Java application that creates a MotherThread thread and a BabyThread thread and starts these two threads. 3.3 Define a Mouth class that includes a synchronized feed(int value) method and a synchronized eat(int value) so that actions of mother feeding and baby eating are synchronized. noted by i = 0~9, to her baby as follows: Month feeds Baby’s mouth Mother takes 0~1000 to feed Baby eats Baby takes 0~1000 to eat mouthの最大値は一つfeedです 実行結果 ex2 class Mouth{ } class MotherThread extends Thread { } class BabyThread extends Thread { } public class MotherBaby {}
© Copyright 2024 ExpyDoc