用java寫一個電梯



import java.util.Comparator;
import java.util.Queue;
import java.util.concurrent.PriorityBlockingQueue;

/**
 * 電梯類
 */
public class Elevator {

    public static final Integer height = 20;
    public static final Integer low = 0;
    public static volatile boolean isUse ; //電梯開啟狀態.需用volatile保持可見性
    public static Integer current = 0; //當前樓層
    public static Integer tempCurrent ; //臨時樓層去重復開門用

    //上隊列
    public static PriorityBlockingQueue<Order> up   = new PriorityBlockingQueue<Order>(height * 3, new Comparator<Order>() {
        public int compare(Order o1, Order o2) {
            return o1.getHeight() - o2.getHeight();
        }
    });

    //下隊列
    public static PriorityBlockingQueue<Order> down =  new PriorityBlockingQueue<Order>(height * 3, new Comparator<Order>() {
        public int compare(Order o1, Order o2) {
            return o2.getHeight() - o1.getHeight();
        }
    });

    static final class Instance{
        static Elevator elevator = new Elevator();
    }
    private Elevator(){}
    public static Elevator getInstance(){
        return Instance.elevator;
    }

    /**
     * 電梯開閘放電使其運行
     */
    public void startRun(){
        this.isUse = true;
        new Thread(new Runnable() {
            @Override
            public void run() {
                try{
                    excutor();
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        }).start();

    }

    /**
     * 電梯關閉
     */
    public void stopRun(){
        this.isUse = false;
    }

    /**
     * 電梯私有運轉方法
     */
    private void excutor () throws Exception{
        boolean isUp = false;
        while(isUse){
            if(up.isEmpty() && down.isEmpty()){
                Thread.sleep(1000);//這里先手動阻塞,阻塞隊列的作用沒體現出來。不知道兩個阻塞隊列如何實現一個非空則喚醒。
            }
            if((current.intValue() == low.intValue()) || !up.isEmpty() ){ //默認先上
                isUp = true;
            }
            if((current.intValue() == height.intValue()) || (up.isEmpty() && !down.isEmpty())){
                isUp = false;
            }

            if(isUp && !up.isEmpty()){
                open(up, isUp, down);
                Thread.sleep(500);
            }else{
                isUp = false;
            }

            if(!isUp && !down.isEmpty()){
                open(down, isUp, up);
                Thread.sleep(500);
            }else{
                isUp = true;
            }
        }
    }

    /**
     * 電梯開門
     */
    private void open(Queue<Order> queue0, Boolean isUp, Queue<Order> queue){
        Order order = queue0.poll();
        if(order == null){
            return;
        }
        if(order.getToUp() == null || order.getToUp() == isUp){ //允許開門的條件
            current = order.getHeight();
            if(tempCurrent != current){
                tempCurrent = current;
                System.out.println("電梯正往"+ (isUp ? "上" : "下")+"走,到" + current + "層了!");
            }
            open(queue0, isUp, queue);
            return ;
        }
        //不允許開門則將其添加到另一個隊列中
        add(queue, order);
    }


    /**
     * 往隊列中添加指令
     */
    private void add(Queue<Order> queue, Order order) {
        Object[] o = queue.toArray();
        for (Object object : o ) {//判斷隊列中是否有相同的指令,有則不添加
            Order oo = (Order)object;
            if(oo.getToUp() == order.getToUp() && oo.getHeight() == order.getHeight()){
                return ;
            }
        }
        queue.add(order);
    }

    /**
     * 人類按電梯
     */
    public void toGo(Integer height, Boolean isUp){
        if(current > height){ //往下的隊列中添加
            add(down, new Order(height,isUp));
        }else{ //往上的隊列中添加
            add(up, new Order(height,isUp));
        }
    }

//=================神奇分割線:指令類================
    /**
     * 電梯運行的指令
     */
    class Order {
        private Integer height; //從幾層叫的電梯
        private Boolean isToUp; //叫電梯的時候按的上還是下按鈕

        public Order(Integer height, Boolean isToUp){
            this.height = height;
            this.isToUp = isToUp;
        }
        public Integer getHeight() {
            return height;
        }
        public Boolean getToUp() {
            return isToUp;
        }
    }

}
//===============神奇分割線 : 測試類=======================
class People{
    public static void main (String[] args) throws Exception{
        Elevator elevator = Elevator.getInstance();

        elevator.startRun();
        elevator.toGo(3,true);
        elevator.toGo(1,null);

        elevator.toGo(4,false);
        elevator.toGo(5,true);

        elevator.toGo(7,false);
        elevator.toGo(6,true);
        elevator.toGo(8,false);

        elevator.toGo(10,false);
        elevator.toGo(9,true);

        elevator.toGo(10,true);
        elevator.toGo(10,null);

//        Thread.sleep(3000); //3秒后斷電。
//        elevator.stopRun();

        elevator.toGo(20,null);
    }
}

==================運行結果如下===============

 

電梯正往上走,到1層了!
電梯正往上走,到3層了!
電梯正往上走,到5層了!
電梯正往上走,到6層了!
電梯正往上走,到9層了!
電梯正往上走,到10層了!
電梯正往上走,到20層了!
電梯正往下走,到10層了!
電梯正往下走,到8層了!
電梯正往下走,到7層了!
電梯正往下走,到4層了!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM