私はこのような何かをしようとしていますが期待通りに動作しませんnのそして、2つのクラスProducer
とConsumer
があります。 Producer
クラスにはput
を呼び出すスレッドがあり、consumer
クラスにはget
を呼び出すスレッドがあります。同期とのスレッドが
public class Q {
int n;
public void put(int n){
System.out.println("Put " + n);
this.n = n;
}
public int get(){
System.out.println("Got " + n);
return n;
}
}
LockClass:
public class LockClass {
private static Object Lock = new Object();
private LockClass(){
}
public static Object getLock(){
return Lock;
}
}
消費者:
私はLockClass.
だから、シングルトンクラスの唯一のインスタンスであるObject lock
を使用して、それを同期しようとしています、ここに私のクラスQであります
public class Consumer implements Runnable {
Thread t;
Q q;
public Consumer(Q q){
this.q = q;
t = new Thread(this);
t.start();
}
/* (non-Javadoc)
* @see java.lang.Runnable#run()
*/
@Override
public void run() {
// TODO Auto-generated method stub
while(true){
synchronized(LockClass.getLock()){
q.get();
}
try {
System.out.println("Consumer slept");
Thread.sleep(1000);
System.out.println("Consumer awake");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
生産者:
public class Producer implements Runnable {
Q q;
Thread t;
int i;
public Producer(Q q){
this.q = q;
t = new Thread(this);
t.start();
i = 0;
}
/* (non-Javadoc)
* @see java.lang.Runnable#run()
*/
@Override
public void run() {
// TODO Auto-generated method stub
while(true){
i++;
synchronized(LockClass.getLock()){
q.put(i);
}
try {
System.out.println("Producer slept");
Thread.sleep(1000);
System.out.println("Producer awake");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
DemoClass:だから
Put 1
Producer slept
Got 1
Consumer slept
Consumer awake
Producer awake
Got 1
Consumer slept
Put 2
Producer slept
Consumer awake
Producer awake
Got 2
Consumer slept
Put 3
Producer slept
Consumer awake
Producer awake
Got 3
Consumer slept
Put 4
Producer slept
、私は実際に作っています:このクラスは、私はこの上記のコードを実行すると、私はこのような何かを得る、
public class DemoClass {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Q q = new Q();
Producer prod = new Producer(q);
Consumer cons = new Consumer(q);
}
}
だから、主な機能を持っていますスレッドがプロデューサとコンシューマの両方でスリープして、コンテキストの切り替えに十分な時間があるようにします。今、両方が同じ時間に眠る必要がある場合、プロデューサーが最初に眠ったら、まず目を覚ますべきです。しかし、私が出力で見ることができるように、プロデューサは最初にスリープしますが、消費者はまだ目を覚ましています。最初に目を覚まされたスレッドがロックを取得し、ロックが解放されるまで別のスレッドが待機する必要があります。
私が期待しているように動作しないのはなぜですか?何か不足していますか?
を指定するために、あなたが考える最初にすべきことは 'BlockingQueue'です。プロデューサはオブジェクトをキューに入れてループします(オブジェクトはこの場合はIntegerオブジェクトになります)。そして、コンシューマはオブジェクトを取り出します。コンシューマがオブジェクトを削除しようとしたときにキューが空の場合、コンシューマはオブジェクトが使用可能になるまでブロックされます。また、キューに上限の制限(多くの場合、良いアイデア)がある場合、キューがいっぱいになるたびにプロデューサがブロックされます。 –
@ jameslarge:ありがとうございました! :) BlockingQueueを調べる –