例外(exception)とは何か

マルチスレッド処理 (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 {}