みんな!
InAndOut
を拡張するクラス ( ) を作成しましたThread
。このクラスは、コンストラクターで 2 つLinkedConcurrentQueue
のentrance
とを受け取りexit
、メソッドはオブジェクトを からにrun
転送します。entrance
exit
私の主な方法では、それぞれにいくつかの値を持つ2 つLinkedConcurrentQueue
のmyQueue1
とをインスタンス化しました。myQueue2
次に、2 つの InAndOut をインスタンス化しました。1 つはmyQueue1
(入口) とmyQueue2
(出口) を受け取り、もう 1 つは (入口)myQueue2
と(出口) を受け取りmyQueue1
ます。次に、両方のインスタンスの start メソッドを呼び出します。
その結果、いくつかの反復の後、すべてのオブジェクトがキューから別のキューに転送されます。つまり、myQueue1
空になり、myQueue2
すべてのオブジェクトが「盗まれます」。しかし、各反復 (100 ミリ秒など) でスリープ コールを追加すると、動作は期待どおりになります (両方のキューの要素番号間の平衡)。
なぜそれが起こっているのか、それを修正する方法は?run メソッドでこのスリープ呼び出しを使用しない方法はありますか? 私は何か間違ったことをしていますか?
ここに私のソースコードがあります:
import java.util.concurrent.ConcurrentLinkedQueue;
class InAndOut extends Thread {
ConcurrentLinkedQueue<String> entrance;
ConcurrentLinkedQueue<String> exit;
String name;
public InAndOut(String name, ConcurrentLinkedQueue<String> entrance, ConcurrentLinkedQueue<String> exit){
this.entrance = entrance;
this.exit = exit;
this.name = name;
}
public void run() {
int it = 0;
while(it < 3000){
String value = entrance.poll();
if(value != null){
exit.offer(value);
System.err.println(this.name + " / entrance: " + entrance.size() + " / exit: " + exit.size());
}
//THIS IS THE SLEEP CALL THAT MAKES THE CODE WORK AS EXPECTED
try{
this.sleep(100);
} catch (Exception ex){
}
it++;
}
}
}
public class Main {
public static void main(String[] args) {
ConcurrentLinkedQueue<String> myQueue1 = new ConcurrentLinkedQueue<String>();
ConcurrentLinkedQueue<String> myQueue2 = new ConcurrentLinkedQueue<String>();
myQueue1.offer("a");
myQueue1.offer("b");
myQueue1.offer("c");
myQueue1.offer("d");
myQueue1.offer("e");
myQueue1.offer("f");
myQueue1.offer("g");
myQueue1.offer("h");
myQueue1.offer("i");
myQueue1.offer("j");
myQueue1.offer("k");
myQueue1.offer("l");
myQueue2.offer("m");
myQueue2.offer("n");
myQueue2.offer("o");
myQueue2.offer("p");
myQueue2.offer("q");
myQueue2.offer("r");
myQueue2.offer("s");
myQueue2.offer("t");
myQueue2.offer("u");
myQueue2.offer("v");
myQueue2.offer("w");
InAndOut es = new InAndOut("First", myQueue1, myQueue2);
InAndOut es2 = new InAndOut("Second", myQueue2, myQueue1);
es.start();
es2.start();
}
}
前もって感謝します!