移动到另一个线程时数据消失
Data disappearing when travelling to another thread
我正在尝试制作模拟等候线和电梯以及个人滑雪者的程序。
现在我的输出很好并且符合预期,直到滑雪者到达升降机顶部然后开始滑雪,这就是线程开始的时候。
我的问题是,滑雪者完成后他应该回到等待队列中,但很多滑雪者都失踪了,而且从来没有 return 排队。
有什么想法吗?
import java.util.Random;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
public class ThreadsAssignment {
// Declare and initalise queues and arrays
public static BlockingQueue<String> liftQueue = new LinkedBlockingQueue<String>(11);
public static BlockingQueue<String> waitQueue = new LinkedBlockingQueue<String>();
public static String toLift;
public static String toWait;
public static String liftFront = "EMPTY";
public static String waitFront;
public static int populatedLift = 0;
public static int pauseLift;
public static int slopeTime;
public static String toPend;
public static int queueSize;
public static void main(String[] args) throws Exception{
// fill both queues list for startup
for(int i = 0; i < 30; i++){
waitQueue.add(Integer.toString(i));
}
for(int j = 0; j < 10; j++){
liftQueue.add("EMPTY");
}
// loop the simulation
while(true){
System.out.println("In Queue " + "(" + waitQueue.size() + "): " + waitQueue);
System.out.println("On Lift " + "(" + populatedLift + "): " + liftQueue + "\n");
// Stop lift for 1 second
try{
Thread.sleep(1000);}
catch (InterruptedException ex) {}
// test if the lift stops
if ((Math.random() * 100) >= 95) {
Random rand = new Random();
pauseLift = rand.nextInt(8001);
System.out.println("Lift paused for " + pauseLift + " milliseconds");
try{Thread.sleep(pauseLift);}
catch (InterruptedException ex){}}
else{}
// get the head of the waiting line then add it to lift, check if any skier is waiting.
liftFront = liftQueue.peek();
if (waitQueue.size() == 0){
liftQueue.add("EMPTY");
}
else{
toLift = waitQueue.take();
liftQueue.add(toLift);
populatedLift++;
}
// if the front of the liftQueue is occupied, call a new skier thread
if (liftFront.equals("EMPTY")){
liftQueue.poll();}
else{
liftQueue.poll();
populatedLift--;
skier s = new skier(liftFront, waitQueue);
new Thread(s).start();
}
}
}
// skier thread
public static class skier extends Thread {
static String name;
static BlockingQueue<String> theQueue;
// Constructor for the thread
public skier(String name, BlockingQueue<String> theQueue){
skier.name = name;
skier.theQueue = theQueue;
}
// run method that makes random skiing time then pends the skier back into the queue
@Override public void run() {
toPend = skier.name;
Random speed = new Random();
slopeTime = speed.nextInt(10001) + 2000;
try {Thread.sleep(slopeTime);}
catch (InterruptedException ex){}
currentThread.
if (waitQueue.contains(toPend)){}
else {try {
waitQueue.put(toPend);
} catch (InterruptedException e){}
System.out.println(toPend + "has been pended");}
}
}
}
以下代码可能会导致滑雪者失踪:
static String name;
static BlockingQueue<String> theQueue;
static
表示 skier
的所有实例将共享最后提交的名称。你必须让所有的滑雪者保密他们的名字:
final String name;
final BlockingQueue<String> theQueue; // this may be left `static` since there's only one instance, but this would be unclean code.
// Or, as an option, let `skier` instances re-use outer class `queue`.
顺便说一句,Java 约定 class 名称以大写字母开头,因此它也应该是 Skier
。
而且你不需要 EMPTY
常量,只需调用 queue.isEmpty()
我正在尝试制作模拟等候线和电梯以及个人滑雪者的程序。 现在我的输出很好并且符合预期,直到滑雪者到达升降机顶部然后开始滑雪,这就是线程开始的时候。 我的问题是,滑雪者完成后他应该回到等待队列中,但很多滑雪者都失踪了,而且从来没有 return 排队。
有什么想法吗?
import java.util.Random;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
public class ThreadsAssignment {
// Declare and initalise queues and arrays
public static BlockingQueue<String> liftQueue = new LinkedBlockingQueue<String>(11);
public static BlockingQueue<String> waitQueue = new LinkedBlockingQueue<String>();
public static String toLift;
public static String toWait;
public static String liftFront = "EMPTY";
public static String waitFront;
public static int populatedLift = 0;
public static int pauseLift;
public static int slopeTime;
public static String toPend;
public static int queueSize;
public static void main(String[] args) throws Exception{
// fill both queues list for startup
for(int i = 0; i < 30; i++){
waitQueue.add(Integer.toString(i));
}
for(int j = 0; j < 10; j++){
liftQueue.add("EMPTY");
}
// loop the simulation
while(true){
System.out.println("In Queue " + "(" + waitQueue.size() + "): " + waitQueue);
System.out.println("On Lift " + "(" + populatedLift + "): " + liftQueue + "\n");
// Stop lift for 1 second
try{
Thread.sleep(1000);}
catch (InterruptedException ex) {}
// test if the lift stops
if ((Math.random() * 100) >= 95) {
Random rand = new Random();
pauseLift = rand.nextInt(8001);
System.out.println("Lift paused for " + pauseLift + " milliseconds");
try{Thread.sleep(pauseLift);}
catch (InterruptedException ex){}}
else{}
// get the head of the waiting line then add it to lift, check if any skier is waiting.
liftFront = liftQueue.peek();
if (waitQueue.size() == 0){
liftQueue.add("EMPTY");
}
else{
toLift = waitQueue.take();
liftQueue.add(toLift);
populatedLift++;
}
// if the front of the liftQueue is occupied, call a new skier thread
if (liftFront.equals("EMPTY")){
liftQueue.poll();}
else{
liftQueue.poll();
populatedLift--;
skier s = new skier(liftFront, waitQueue);
new Thread(s).start();
}
}
}
// skier thread
public static class skier extends Thread {
static String name;
static BlockingQueue<String> theQueue;
// Constructor for the thread
public skier(String name, BlockingQueue<String> theQueue){
skier.name = name;
skier.theQueue = theQueue;
}
// run method that makes random skiing time then pends the skier back into the queue
@Override public void run() {
toPend = skier.name;
Random speed = new Random();
slopeTime = speed.nextInt(10001) + 2000;
try {Thread.sleep(slopeTime);}
catch (InterruptedException ex){}
currentThread.
if (waitQueue.contains(toPend)){}
else {try {
waitQueue.put(toPend);
} catch (InterruptedException e){}
System.out.println(toPend + "has been pended");}
}
}
}
以下代码可能会导致滑雪者失踪:
static String name;
static BlockingQueue<String> theQueue;
static
表示 skier
的所有实例将共享最后提交的名称。你必须让所有的滑雪者保密他们的名字:
final String name;
final BlockingQueue<String> theQueue; // this may be left `static` since there's only one instance, but this would be unclean code.
// Or, as an option, let `skier` instances re-use outer class `queue`.
顺便说一句,Java 约定 class 名称以大写字母开头,因此它也应该是 Skier
。
而且你不需要 EMPTY
常量,只需调用 queue.isEmpty()