有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java数据在移动到另一个线程时消失

我正在尝试制作一个程序,模拟等待线和升降机,以及单个滑雪者。 现在,我的输出是好的,正如预期的那样,直到滑雪者到达电梯顶部,然后开始滑雪,这是线程开始。 我的问题是,一旦滑雪者完成了,他就应该把自己吊回等待的队伍中,但是很多滑雪者都失踪了,再也没有回到队伍中

有什么想法吗

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) 个答案

  1. # 1 楼答案

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

    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()