旅行到另一个线程时数据消失

时间:2015-10-22 09:16:04

标签: java multithreading queue

我正在尝试制作模拟等候线和升降机的程序,以及个人滑雪者。 现在我的输出很好并且如预期的那样直到滑雪者到达升降机的顶部然后开始滑雪,这是线程开始的时候。 我的问题是,一旦滑雪者完成后他就应该重新回到等候线上,但是很多滑雪者都会失踪,并且永远不会回到滑雪道。

有什么想法吗?

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");}
        }
    }   
}

1 个答案:

答案 0 :(得分:0)

以下代码可能会导致滑雪者失踪:

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有使用大写字母开始类名的惯例,所以它也应该是Skier

并且您不需要EMPTY不变,只需致电queue.isEmpty()