[an error occurred while processing this directive]
[an error occurred while processing this directive]
[ThTest.java]
class Runner implements Runnable{
public void run() {
for(int i = 0; i < 3; i++) System.out.println("count :" + i);
}
}
public class ThTest {
public static void main(String[] args){
Runner runner = new Runner();
Thread t = new Thread(runner);
t.start();
}
}
ま、こんな感じかな。
Runnerのrun()が実際に走るスレッドになります。
mainの方はまとめると
public static void main(String[] args){ (new Thread(new Runner())).start(); }という荒っぽいこともできます。
[MyQueue.java]
import java.util.List;
import java.util.ArrayList;
public class MyQueue{
private List q = new ArrayList();
public void enqueue(Object o){
synchronized(q){
q.add(o);
q.notify();
}
}
public Object dequeue() {
synchronized(q){
while(q.isEmpty())
try{ q.wait();} catch (InterruptedExceprion e){}
return q.remove(0);
}
}
}
synchronized(q)というのは、「このブロック内ではqに同時に複数アクセスできない」
ということを指定します。
ここで、複数の同じオブジェクトを対象とするsynchronizedでも、それぞれは連携して
動作し、同時に一つのブロックしか動きません。
例えばenqueue()とdequeue()が同時に呼ばれても、実際にqに触ることが出来るのは
片方だけで、もう片方はその直前でブロックされます。
while(q.isEmpty()) q.wait(100);という風に書くと、100m秒おきにキューが空でないかチェックし、空でなくなったら 次の処理に移ることができるようになっています。
while(q.isEmpty()) q.wait();というふうに書くと、スレッドは永久にブロックされます。 って、本当に永久にブロックされたら困るわけで、このブロックを起こす手段がちゃんと用意されています。 それがq.notify()というメソッドで、どこか別のブロックでこのnotifyが呼ばれると、 waitは解除されます。ここでは、enqueueの方でnitify()してるので、 dequeueのwaitはキューが空でなくなったら解除されます。
[Qtest.java]
import dla.MyQueue;
class Producer implements Runnable{
MyQueue q;
Producer(MyQueue _q){q = _q;}
public void run() {
for(int i = 0; i < 3; i++){
q.enqueue("Nexus" + i);
try{
Thread.sleep(1000);
} catch (Exception e){}
}
}
}
class Consumer implements Runnable{
MyQueue q;
public Consumer(MyQueue _q){q = _q;}
public void run() {
for(int i = 0; i < 3; i++){
try{
System.out.println((String)q.dequeue());
Thread.sleep(1);
} catch (Exception e){}
}
}
}
public class Qtest {
public static void main(String[] args){
MyQueue q = new MyQueue();
(new Thread(new Producer(q))).start();
(new Thread(new Consumer(q))).start();
}
}
データを入れるほうは1000msecおきにenqueueし、取り出すほうは1msecおきにdequeueするから、
waitが何度も呼ばれている計算になります。