CAFE BABE リスト 5 生産者・消費者問題 import j ava. util . Random; public class ProducerConsumer { public static final int BUFFER-SIZE = 5 ; public static void main(String args ロ ) { final Buffer buffer = new Buffer (BUFFER—SIZE) ; new Thread() { / / 生産者スレッド Random random = new Random ( ) ; public void run() { while (true) { buffer. put (random. nextlnt ( ) ) ; ・ 1 0 0 N td ・ 1 •H O d synchronized void put (int i) { while (((tail + 1 ) % size) / / パッフアが満杯のあいだ待つ System. out . print1n("Buffer is fu11. " ) ; try { wait ( ) ; } catch (InterruptedException e) { } buffer [head] head = (head 十 1 ) % size; 110tifyA11() ; head) { } . start(); new Thread() { / / 消費者スレッド public void run() { while (true) { System. out . println(buffer. get()) ; synchronized int get() { tail) { while (head / / パッフアが空のあいだ待つ System. out . print1n("Buffer is empty. try { wait() ; } catch (InterruptedException e) { } int i = buffer [tail] ; (tail + 1 ) % size; tai1 notifyA11() ; 1 ; } . start(); class Buffer { private int buffer ロ , private int Size ; private int head ; private int tail; Buffer(int i) { new int [i] ; buffer ducer) がデータを書き込み、消費者 (consumer) がデー タを取り出して使用する間題です。このとき、共有バッフ アか謚れないように管理する必要があります。 サンプル・プログラムをリスト 5 に示します。 このフログラムでは、バッフアは有限長のリンクンヾッフ アで、任意の整数を書き込む生産者スレッドと、 ノヾッファ から整数を取り出して標準出力に出力する消費者スレッド か並行に乍します。 なお、本来はバッフアが空の場合と : 淋不の場合とでは別 void sleep(long ミリ秒 ) の条件変数を利用すべきですが、 こでは Java の制約の void sleep(long ミリ秒 , int ナノ秒 ) ために 1 つの条件変数だけを使っています。 sleep() メソッドを実行している最中のスレッドをはか sleep() メソッド のスレッドがインタラブトしたときは、 InterruptedEx- wait() メソッドと同様に、タイムアウトを設定できる ception 例外が発生します。インタラブトについては、機 メソッドとして sleep() メソッドがあります。 sleep() メ 会をあらためて詳しく説明します リスト 6 に、約 1 秒間隔て驃気出力に出力する簡単な ソッドは、現在実行中のスレッドを一日亭止し、指定され た時間カ過したあとに実行を再開します。 プログラムを示します。ただし、スレッドが実行を一日亭 リスト 6 sleep() の実行 public class S1eepTest { public static void main(String args ロ ) { 0 ; i く 100 ; i + + ) { for (int i = try { Thread. currentThread() . sleep ( 1000 ) ; } catch (InterruptedException e) { } ; System. out. println(i) ; 114 UNIX MAGAZINE 2000.7
リスト 4 同期したプログラム ( 2 ) public class Samp1e3 { public static void main(String args ロ ) final SharedData3 data new SharedData3 ( ) ; data ・ print ( ) ; while (true) { public void run() new Thread( ) { } . start(); data. change ( ) ; while (true) { public void run() new Thread() { } . start(); class SharedData3 private int a ロ private boolea れ Java フログラミング・ノート while (modified) { try { wait ( ) ; } catch (InterruptedException e) { } for (int i = 0 ; i く a. length; i + + ) { a[i] = (a[i] + 1 ) % 10 ; modified = true ; notifyA11() ; synchronized void print ( ) { while ( !modified) { try { wait ( ) ; } catch (InterruptedException e) { } for (int i = 0 ; i く a. length; i + + ) { System. out . print(a[i] ) ; System. out . println() ; 5 , 1 , 6 , modified 2 , 3 , 4 , 7 , 8 , 9 } ; false; synchronized void change() { このプログラムを実行すると、次のような出力カ等られ 9012345678 8901234567 7890123456 6789012345 5678901234 4567890123 3456789012 2345678901 1234567890 ます。 ます。 UNIX MAG AZINE 2000.7 件が成立したのかを判定しています。 し、 wait() メソッドを実行したスレッド側でどちらの条 tify() メソッドの代わりに notifyAll() メソッドを使用 モニターは 1 つの条件変数しかもてません。そこで、 no- ぞれ独立に通知する必要がありますが、 Java では 1 つの た場合の 2 つの条件があります。したがって、本来はそれ このプログラムでは、変更されていない場合と変更され ラムカ噫図どおりに重川乍しているのが分かります。 図 7 に示すタイミングでメソッドが実行され、プログ modified = false; notifyA11() ; 図 7 メソッドの実行タイ changeData() notify() スレッド 1 ミンク ( 3 ) wait() スレッド 2 - printData() 時間 113 これは、有限長の共有バッフアに対して生産者 (pro- にも適用できます。 な並行プログラミング問題である、、生産者・消費者間題 " ときの間題を示す意図的な例でした。同し考えは、典型的 リスト 4 のプログラムは、同期が正しくおこなわれない 生産者・消費者問題 おくはうがよいでしよう。 けではないので、適用範用がより広くなるように実装して と叫屯化できますが、それによって性能が大きく変わるわ れています。それぞれ 1 つのスレッドに限定すればもっ るスレッドか莪数になっても正しく重川するように実装さ このプログラムは、データを変更するスレッドや出力す
CAFE BABE monitorenter イイと monitorexit イイカゞ用意さオ L てい ます。スレッドは、式を評価してオプジェクトの参照を 計算してから、 synchronized プロックを処理する前に monitorenter 命令を実行してオプジェクトをロックし、 処理の終了または中断後に monitorexit 命令を実行して オプジェクトをアンロックします。 Java では synchro- nized キーワードを用いた抽象度の高い構文で言当するの て、、 monitorenter イイと monitorexit - 命・令カゞつねに正 しく対になります。 クラスをロックする場合は synchronized 文を利用し、 そのクラスのインスタンスに対して getClass() メソッド を用いて CIass オプジェクトを取得してロックします。 リスト 1 のフログラムカ噫図どおりに動くように 同期したプログラム ( 1 ) synchronized ( F00. class) { void bar() { class F00 { に CIass オプジェクトを取得することができます。 JDK 1.1 以降では、 class キーワードを使って、同様 synchronized (getClass ( ) ) { void bar() { class F00 { syn- グラムカ噫図したとおりに動いているのが分かります。 ら、図 5 に示すタイミングでメソッドが実行され、プロ このプログラムの実行結果は以下のようになることか します。 chronized メソッドを用いて記述した例をリスト 2 に示 110 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 5678901234 5678901234 5678901234 リスト 2 同期したプログラム ( 1 ) public class Samp1e2 { public static void main(String args ロ ) { final SharedData2 data new SharedData2 ( ) ; new Thread() { new Thread ( ) { }. start(); data. change ( ) ; while (true) { public void run() { SharedData2 { } . start(); data. print() ; while (true) { public void run() { class private int a ロ = { 0 , 1 , 2 , 3 , 5 , 6 , 7 , 8 , synchronized void change ( ) { f or ( int i = 0 ; i く a. 1 ength ; (a [i] + 1 ) % 10 ; aCi] synchronized void print ( ) { for (int i = 0 ; i く a. length; System. out ・ print (a[i] ) ; System. out . println() ; 図 5 メソッドの実行タイミング ( 2 ) changeData() スレッド 1 ー スレッド 2 - printData() this を指定しない synchronized 文 4 , 9 } ; 時間 synchronized メソッドや、、、 this" を指定した syn- chronized 文では、その手続きカ躾装されているオプジェ クトをロック、アンロックします。しかし、 synchronized 文の式に this 以外のオプジェクトを指定することで、同 UNIX MAGAZINE 2000.7
CAFE BABE リスト 1 同ヾ冫立要な例 public class Samp1e1 { モニター CZ 念 モニター 図 2 メソッドの実行タイ changeData() スレッド 2 - スレッド 1 ミング ( 1 ) public static void main(String args ロ ) { final SharedData data = new SharedData() ; data ・ print() ; while (true) { public void run() new Thread() { }. start(); data. change ( ) ; while (true) { public void run() new Thread() { 図 3 p ri nt Data() 同時には / スレッド 1 手続き A 手続き B 時間 共有資源 } . start(); class SharedData { private int void change ( ) { for (int i ー 0 ; a[i] void print ( ) { for (int i = 0 ; 実行できない、・ スレッド 2 5 , 1 , 6 , 2 , 7 , 1 (a Ci] + 1 ) % 10 ; i く System. out. println() ; System. out . print (a[i] ) ; く a. length; a. length; 3 , 十十 ) i 十十 ) 8 , 9 } ; 4 , や、、 6789012345 " のように、すべて異なる数字で出力さ れなけ川まならないのですが、実行結果はそうなっていま せん。 これは、あるスレッドが配列の値を変更している最中で も、図 2 に示すようなタイミングで別のスレッドか値を読 み出しているからです。 モニター Java では、モニター (monitor) を用いてスレッドを同 期させています。モニターとは、抽象データ型を並列プロ グラミングに対して拡張した概念てす。つまり、モニター は並列プログラミングに必要な同期についての実装を隠蔽 し、より扱いやすくしたものといえます。 モニターは、複数のスレッドが共有する変数などの共 108 有資源と、それを外部から操作する手続きをもっています ( 図 3 ) 。これらの手続きは排他制御され、同時には実行で きないので、競合伏態は起こりません。 このように、ある手続きを実行中にほかの手続きか割り 込めない場合は、アトミック (atomic) な手続きであると いいます。 モニターは、変数を妾共有する力法にくらべると、実 装の田を知らなくても手続きを実行でき、アクセス手段 の制限も可能なため、バグを大塩に減らせます。 ただし、一殳にはすべての手続きを孑羽勺におこなう必 要はなく、同時に実行してよい場合もあります。そこで、 Java では同期が必要なメソッドやプロックだけをプログ ラマーカ甘旨定するように定義されています。 さらに、 Java ではモニターの再帰的な呼出しも可能で す。たとえば、 SoIaris スレッドの相互排除 (mutex) ロ ックでは、再帰的な呼出しは許されないので、セルフ・デ ッドロック (selfdeadlock) やリカーシプ・デッドロッ ク (recursive deadlock) を起こさないように注意架く実 装しなけれはなりませんが、 Java ではその必要はありま せん。 ロック Java では、同時に複数のスレッドがアクセスできない ように、オプジェクトをロック (lock) することでモニ UNIX MAGAZIN E 2000.7
CAFE BABE リスト 8 デッドロック public class Samp1e5 Object 10CkA = new Object() ; Object 10CkB = new Object ( ) ; int a = 0 ; int b = 0 ; System. out. println()l : synchronized (10ckB) { synchronized (10ckA) { while (true) { public void run() { Thread tl = new Thread() { void go() { sample ・ go() ; Samp1e5 sample = new Samp1e5() ; public static void main(String args ロ ) " 十 Thread. currentThread() . yield ( ) ; Thread t2 = new Thread ( ) { public void run() { while (true) { synchronized (10ckB) { synchronized (10ckA) { a 十十 ; System. out. print1n("2: 十 " 十 Thread. currentThread() . yield ( ) ; tl . start() ; t2. start() ; 条件同期が原因のデッドロック かの言語にくらべてバグが多にしにくいといえます。 とによるデッドロックも発生しません。したがって、 は 条司期が原因のデッドロックは、 wait() メソッドを 実行しているスレッドに対して notify() されないために 発生します。 相互排除の場合とは異なり、 wait() メソッドと no- 116 リスト 9 finally 節の notify() メソッド synchronized void f00 ( ) { try { } finally { notifyA11() ; tify()/notifyAll() メソッドか正しく対になること焉正 するのはプログラマーの責任です。また、モニターに対し て条件変数が 1 っという制約のある Java では、 wait() メソッドを実行しているスレッド側で条負半」定をおこなっ ている場合には、 notify() メソッドではなく notifyAll() メソッドを実行し、複数のスレッドにプロードキャストす る必要があります。 notify() メソッドを実行し忘れる例のうち、発見しに くいの刎列外の発生によるメソッドの実行の中断です。 の場合には、 notify() が正し信当されていても実行され すにデッドロックします。このようなときは、リスト 9 に示すように finally 節で notify() を宣言するとよいで しよう。 特殊なケースとして、メソッドの throws 節で宣言す る必要のない RuntimeException や Error が発生する 場合カ挙げられます。通常は、この種の RuntimeExcep- tion や Error をキャッチする必要はありませんが、プロ グラムや工竟によっては、これらの一部をキャッチして状 態の回復をおこなうことがあります。 たとえは、一碚にの Servlet Engine は OutOfMemory- Error が発生したときに、これをキャッチして処理を続 行します。これは、エラーの発生の原因になった特定の セッションを中断するだけでよい場合が多いことと、ヒー プなどの不足をプログラムで完全に予測するのは難しく、 OutOfMemoryError が発生した時点で実行を終了する ようでは運用上困るからです。 OutOfMemoryError は、プログラム中のオプジェク トを生成する任意の箇所て、発生するため、このような畤殊 な環竟での条件同期はとくに注意して実装する必要があり ます。 スターベイション デッドロックを起こしてはいないが、いつまて経っても スレッドがモニターをう昇できないなどの理由で、実行さ UNIX MAGAZINE 2000.7
リスト 7 sleep() とモニター public class Samp1e4 { public static void main(String args ロ ) Samp1e4 sample = new Samp1e4 ( ) ; synchronized void t2. start(); tl . start(); printMessage("b") ; public void run() { Thread t2 = new Thread() printMessage("a") ; public void run() { Thread t 1 = new Thread() void go() { sample ・ go ( ) ; try { System. out . println(message) , while (true) { printMessage(String message) { UNIX MAGAZINE 2000.7 } catch ( InterruptedException e) { } Thread. currentThread() . sleep ( 1000 ) ; 定日判りどおりに動くとはかぎりません。通常は、スレッ ポリシーや割込み ) 芯嚮が異なるので、タイマーカ指 ・ OS や Java VM の実装によって、スケジューリング・ すしも正確に一 -- ・致するわけではありません。 スレッドカ躾際に停止する日判りは、指定したとかなら くっか用意されています。しかし、以下のような理由から、 ができる wait() や sleep() 、扣ⅲ ( ) などのメソッドがい java. lang. Thread クラスには、タイムアウト値の拓疋 タイムアウト値について ち続けます。 1 つのスレッドはオプジェクトがアンロックされるのを待 プジェクトをロックしたスレッドか実行されますが、もう 簡単列をリスト 7 に示します。この例では、最初にオ ままである点に注意してください。 止している最中であっても、モニターの所有権をイ尉寺した Java フログラミング・ノート 操作がかならす対になるため、アンロック操作を忘れたこ プ・デッドロックカ起こらす、ロック操作とアンロック か滸されているので、セルフ・デッドロックとリカーシ Java のスレッド・プログラミングでは再帰的なロック コーディングする必要があります。 ではこのようなバグが発生しやすいので、とくに注意架く this 以外のオプジェクトを指定する synchronized 文 バルなロックを使うことて埆夬できます。 序をつねに同しにするか、複数のロックを使わすにグロー このようなロックの順序が原因の場合には、ロックの順 ロックか、発生します。 るのを待っために、そオ ) ま処理か進行しなくなりデッド レッド 2 は lockA オプジェクトをロックできるようにな うになるのを待ち、 lockB オプジェクトをロックしたス したスレッド 1 は lockB オプジェクトをロックできるよ のプログラムを実行すると、 I 。 ckA オプジェクトをロック をロックする順番が逆だという点に注目してください。 ぞれのスレッドが、この 2 つのロック用のオプジェクト に lockB オプジェクトを使用しています。ただし、それ lockA オプジェクトを、 b という変数をロックするため このプログラムでは、 a という変数をロックするために その簡単な例をリスト 8 に示します。 ます。 レッドがモニターを解放するのを待ち続けるために発生し 相互排除が原因で発生するデッドロックは、ほかのス 相互排ド劒ヾ原因のデッドロック 発生します。 デッドロックは、おもに相互排除と条件同期によって 不可能になる状態のことです。 のスレッドの実行を永遠に待ち続けて、そオび丿ま . の実行が デッドロック (deadlock) とは、あるスレッドがはか テッドロック より細かく時間を指定しても無視されます。 リ秒単位のタイマーを使用している OS 上では、それ 提供するタイマーの精度に依存します。たとえは 10 ミ 実際にどの程度の精度までク旨定ができるかは、 OS が これらのメソッドではナノ秒単位の指定もできますが、 ます。 ドカ躾際に停止するは指定した時間より大きくなり 115
Java フログラミング・ノート リスト 10 セマフォの実装 れない状態か読くことをスターベイション (starvation public class Semaphore { と呼びます。これは、プログラムの実装かま行タイミング private int count ; に依存するような場合に発生します。スターベイションの public Semaphore (int concurrency) { 完全な回避は、デッドロックの回避よりも複雑です。 this . count concurrency ; ほかの同期プリミティフの実現 並行プログラミン久並列プログラミングでは、モニタ ー以外にさまざまな同期プリミテイプが使われます。これ らの同期プリミテイプは、モニターを用いて実装すること もできます。 たとえば、よく使われる同期プリミテイプとしてセマ フォ (semaphore) があります ( セマフォというのは、 の腕木式信号機の意味です ) 。 セマフォは内部にカウンタをもち、カウンタを操作する アトミックで孑勺な操作として P 操作 ( オランダ語の prolagen と passeren から命名 ) と V 操作 (verhogen と vrygeven から命名 ) が定義されています。 P 操作は、セマフォか管理する領域に入るときに実行す る操作で、カウンタの値が正ならば 1 減少します。そオ LJ ユ 外の場合には、カウンタの値が正になるまで待機します。 V 操作は、セマフォカ理する領域を出るときに実行する 操作で、カウンタの値を 1 増加させます。 セマフォを使えば、同時実行可能なスレッド数を制御す ることができます。とくに、カウンタの初期値が 1 の場合 はパイナリ・セマフォ (binary semaphore) と呼び、任 意の整数値の場合はカウンティング・セマフォ (counting semaphore) と呼びます。 セマフォの実装例をリスト 10 に示します。 volatile 宣三 マルチプロセッサ・マシン上で複数のスレッドが共有 変数を使用したり代入する場合には、高速化のために値を イ乍業メモリ (working memory) にコピーして作業するこ とかめられています。この場合、メインメモリの値をマ スターコピー (master copy) 、作業メモリの値を作業コ ピー (working copy) と呼びます。 このような工竟下で、 2 つのスレッドか変数をイ目した り代入する簡単なクラスの例をリスト 11 に示します。 これが、この環境でどのように処理されるかを図 8 に示 します。 synchronized void boolean P ( ) { while (count く = 0 ) { try { wait() ; } catch (InterruptedException (x) { C ount ー synchronized public void V ( ) { count 十十 ; notify() ; リスト 11 変数吏用と代入 ( 1 ) class Test { int a = 0 , b = 0 ; void one() { b = 2 ; void two() { a + b; int C System. out . println(c) ; ー ます、スレッド 2 カ哄有変数 a を使用 (use) する場合 を考えます。このときには、ますメインメモリから値を査 み出し (read) たのち、竹喋メモリ 2 に中幻 (load) しま す。スレッド 2 は、この作業メモリにコピーされた値 a ” を使用 (use) します。 次に、スレッド 1 が共有変数 a に代入 (assign) する 場合を考えてみましよう。このときには、ます竹業メモリ 上の値 a ' を変更します。同時に、その値をメインメモリ に輔医し (store) 、 a の値として書き込みます (write)o この場合、次のような問題が発生します。 ・マスターコピーといくつかの作業コピーの値がつねに 一致しているわけではないので、 read-load および store—write のタイミングによっては、予期せぬ動作 カ備き起こされます。 1 一二ロ 117 UNIX MAG AZIN E 2000.7
RFC ダイジェストー 表 5 分科会ごとの集計 ( 2 ) ( うお・ようしろう、おがしわ・のぶお、 糸懿胸工リア (Routing Area) 6 2 1 0 4 3 1 0 4 3 1 0 0 mpls: Multiprotocol Label Switching gsmp. GeneraI Switch Management Protocol mobileip. IP Routing for WireIess/Mobile Hosts isis: IS-IS for IP lnternets idr. Inter-Domain Routing udlr: UniDirectionaI Link Routing bgmp. Border Gateway MuIticast Protocol dlswmib: Data Link Switching MIB idmr: lnter-Domain Multicast Routing 0 manet: MobiIe Ad-hoc Networks mospf. Multicast Extensions to OSPF msdp. MuIticast Source Discovery Protocol ospf. Open Shortest Path First IGP pim. Protocol lndependent Multicast rip: Routing lnformation Protocol snadlc: SNA DLC Services MIB vrrp. VirtuaI Router Redundancy Protocol セキュリティ・エリア (Security Area) secsh: Secure Shell pkix: Public-Key lnfrastructure ( X. 509 ) openpgp. An Open Specification for Pretty Good P rivacy cat : Common Aut henticat ion Technology smime: S/MIME MaiI Security xmldsig: XML DigitaI Signatures aft: Authenticated Firewall Traversal ipsp: IP Security P01icy トランスポー megaco: Media Gateway Control si gt ran. S ignal ing Transp ort ippm. IP Performance Metrics malloc: Multicast-Address Allocation 0 ipsec: IP Security Pr0tocol ipsra: IP Security Remote Access idwg. lntrusion Detection Exchange Format 0tp: One Time Password Authentication st ime : Secure Network Time P r0t0C01 spki: Simple Public Key lnfrastructure tls: Transport Layer Security wts: Web Transaction Security ト・エリア (Transport Area) intserv: lntegrated Services iptel: IP TeIephony ecm: Endpoint Congestion Management 0 diffserv: Differentiated Services mmusic: Multiparty Multimedia Session Control pint: PSTN and lnternet lnternetworking rsvp. Resource Reservation Setup Protocol spirits: Service ⅲ the PSTN/IN Requesting ln- S ervice sip. Session lnitiation Protocol tcpimpl: TCP lmplementation enum. TeIephone Number Mapping avt: Audio/Video Transport 堋者サ fyiup. FYI Updates run. Responsible Use of the Network us ・ wg.• User Services issll: lntegrated Services over Specific Link Layers nat: Network Address Translators nfsv4: Network File System Version 4 oncrpc: ONC Remote Procedure Call pilc: Performance lmplications of Link Character- istics rmt: ReIiabIe MuIticast Transport rohc: Robust Header Compression tsvwg: Transport Area Working Group ービスエリア (User Services Area) 0 weird: Web EIucidation of Internet-Related De- ラフトである。 まとめ UNIX MAGAZINE 2000.7 ターネット・ドラフトの公け羽大況を紹介する。 月中旬から 6 月中旬にかけて公開された RFC と、イン ドラフト公報」の概要を紹介した。次回は 2000 年 5 ターネットの標準化について解説し、「インターネット・ 今月は、インターネット・ドラフトの彳齬リを中心にイン velopments すえなが・ひろき 北陸先立物支術大完大学 ) 161
表 3 35 28 27 22 19 18 17 活発に活動している IETF 分科会覧 過去 6 カ月間 ( 1999 / 11 / 16 ~ 2000 / 5 / 15 ) mobileip: IP Routing for Wireless/MobiIe Hosts avt: Audi0/Video Transport dhc: Dynamic Host Configu- rat ion mpls: Multiprotocol Label Switching lpp: lnternet Printing Prot0- C01 cat: Common Authentication Technology ipsec: IP Security Protocol dnsext: DNS Extensions ngt rans : Next ( ; ・ enerat ion Transition smime: S/MIME Mail Secur- ity 19 17 14 13 12 11 10 過去 3 カ月間 ( 2000 / 2 / 16 ~ 2000 / 5 / 15 ) dhc: Dynamic Host Configu- ration ipp: lnternet Printing Proto- C01 avt: Audio/Video Transport mpls: \'lultiprotocol LabeI Switching sigtran: Signaling Transport dnsext: DNS Extensions ngtrans: Next Generation Transition aaa: Authentication, Autho- rization and Accounting cat : C0mm011 Authent icat ion Technology pkix: Public-Key lnfrastruc- ture ( X. 509 ) 6 4 3 2 日 FC ダイジェストー 過去 1 カ月間 ( 2000 / 4 / 16 ~ 2000 / 5 / 15 ) mpls: Multiprotoc01 Label Switching 同数のう斗会が多数のため割愛 sigtran: Signaling Transport policy: Policy Framework ture ( X. 509 ) pkix: Public-Key lnfrastruc- ration dhc: Dynamic Host Configu- secsh: Secure Shell Monitoring rmonmib: Remote Network trol megaco: Media Gateway C01 ト rization and Accounting aaa: Authentication, Autho- を集計した。その結果を表 4 ~ 5 に示す。 MPLS 分科会 UNIX MAGAZINE 2000.7 Specification Use of Label Switching on Frame Relay Networks [d raft-ietf-mpls-fr-04. txt] 使って運用される MPLS 技術について論している。 ATM VC を扱う LDP と、その結果確 : 立 : される経路を LDP と ATM VC スイッチングを用いた MPLS MPLS using LDP and ATM VC Switching [draft-ietf-mpls-atm-03 txt] を簡単に紹介する。 MPLS に関連する個人名義のインターネット・ドラフト MPLS 分利会が公開したインターネット・ドラフトと、 言墟侖を並行しておこなっている。 から周辺技術にいたるまで、たいへん多くの分野に関する の標準化を目的としており、現在 MPLS アーキテクチャ MPLS うト会は名前のとおり、 MPLS にする技術 bel Swtiching) 分科 - 会である。 ト・ドラフトを公開したのは MPLS (MultiProtocoI La- 今回対象とした期間中にもっとも多くのインターネッ フレームリレー・ネットワーク上でのラベル・スイッチン グの利用に関する詳細 フレームリレー・ネットワーク上で PLS を利用する ためのモデルや財隨を定義している。 [draft-ietf-mpls-loop-prevention-03. txt] MPLS Loop Prevention Mechanism MPLS のルーフ防止機構 MPLS におけるラベルスイッチ・パス (LSP) の糸習各 ループの方」 - 日冓を提案している。 [draft-ietf-mpls-lsr-mib-03 txt] [draft-ietf-mpls-lsr-mib-04 txt] MPLS Label Switch Router ManagementInformation Base Using SMlv2 SMlv2 を用いた MPLS ラベルスイッチ・ルータ M 旧 MPLS 用のルータ LSR (Label Switch Router) を 管理するための MIB を定義している。 [draft-ietf-mpls-multicast-01. txt] Framework forIP MuIticast in MPLS MPLS における旧マルチキャストのフレームワーク MPLS 工竟における IP マルチキャストのフレームワ ークについて言侖している。 159
Java フログラミング・ノート リスト 3 this をキ諚しない synchronized 文 new Object() ; Object lock int a = 0 ; int b = 2 ; (lock) { synchronized 十十 ; b + = 2 ; 図 6 条件変数を用いた同期の手順 クリティカル・セクション ロック待ち集合 待機集合 0 2 ) 期された手続きカ義されているオプジェクトとは異なる オプジェクトをロック、アンロックすることもできます。 簡単な例をリスト 3 に示します。 モニターではなく、たんにロックとして使用するこの ようなコーディングは、性能のポトルネックの解消や、ク ラス言 t 十の要求がある場合によくおこなわれます。しか し、データ隠蔽や同期管理の容易さというモニターの利点 が失われ、 public な共有変数を直孑作したり、ロック するオプジェクトとは別の共有変数を操作するため、発見 しにくいバグを生む可能性か高くなります。 このような場合は、とくに注意架く実装するのはもちろ ん、 protected 旦暠や内部クラスなどのガ去を利用してス コープを限定するようにじ掛けるとよいでしよう。 条件変数 モニターの導入により、複数のスレッドか竸合するこ となく処理できるようになります。しかし、実行条件か複 雑な場合にはモニターを獲得できても実行できるとはかぎ りません。条負初成立をルーフ。て調べるのが一番簡単です が、 CPU 資源を無馬貴いしてしまいます。 そこで、条件が成立するまでスレッドを待機させ、ま た条件が成立したときに待機していたスレッドに通知する 機能を実現するために、条件変数 (condition variable) が用意されています。条件変数とはモニター内でイ吏用され る、代入や参照を目的としない特殊な変数です。牛変数 は、現在どのスレッドか待機しているかを知るためにスレ ッドの待合 (wait set) をもっています。オプジェク トが生成された点では、待機集合は空です。 条件変数を用いた同期の具勺な手順は、以下のとおり 1. オプジェクトをロックします ( 図 6-1 ) 。 2. 実行条件か整っていない場合、条件変数に対して wait wait ( & unlock) 3 ) signal loc k 5 ) unlock 操作を実行します ( 図 6 ー 2 ) 。このとき、スレッドはオ プジェクトをアンロックしてから待機集合に入るので、 ほかのオプジェクトがクリティカル・セクションを実 行できます。 3. 待機中のスレッドの実行条件か整った場合には、 signal 操作を実行して知らせます。このとき、スレッドはロッ ク待ち集合に入ります ( 図 6 ー 3 ) 。 4. スレッドはロックをふたたひ獲得してから、処理を実行 します ( 図 6-4 ) 。 5. 処理を終えたあと、オプジェクトをアンロックします ( 図 6 ー 5 ) 。 111 UNIX MAGAZINE 2000.7