Java异步问题

时间:2014-12-06 20:15:39

标签: java

所以我的代码就像我想要的那样工作我唯一的问题就是这个......基本上我有一个主要类来控制铁路轨道上的大门,当火车接近或越过轨道时门应该关闭的两个轨道中的一个。我遇到的唯一问题是当门打开或关闭垃圾邮件时的声明,例如每当它执行某些操作时会发生3-5次垃圾邮件,如果关闭它将会发生...

GATE: Closing
GATE: Closing
GATE: Closing
GATE: Closing
GATE: Closing
GATE: Closed

我想知道为什么会发生这种情况,这是我的Gate类和Main类的代码

public class Gate {

    private boolean isClosed = false;
    private boolean closing = false;
    private boolean opening = false;

    public Gate(){

    }

    public void close(){
        if(!(isClosing() == true)){
            Runnable task = new Runnable() {
                public void run() {
                    try { 
                        setClosing(true);
                        setOpening(false);
                        System.out.println("GATE: Closing");
                        Thread.sleep(400);
                        System.out.println("GATE: Closed");
                        setClosed(true);
                        setClosing(false);
                    }catch(Exception ex){

                    }
                }
            };
            new Thread(task, "closeThread").start(); 
        }
    }

    public void open(){
        if(!(isOpening() == true)){
            Runnable task = new Runnable() {
                public void run() {
                    try { 
                        setOpening(true);
                        System.out.println("GATE: Opening");
                        Thread.sleep(400);
                        setOpening(false);
                        if(closing == false){
                            setClosed(false);
                            System.out.println("GATE: Opened");
                        }
                    }catch(Exception ex){

                    }
                }
            };
            new Thread(task, "openThread").start(); 
        }
    }

    public boolean isClosed(){
        return isClosed;
    }

    public boolean isClosing(){
        return closing;
    }

    public boolean isOpening(){
        return opening;
    }

    public synchronized void setClosing(boolean t){
        closing = t;
    }

    public synchronized void setOpening(boolean t){
        opening = t;
    }

    public synchronized void setClosed(boolean t){
        isClosed = t;
    }
}


public class Controller {
    public static void main(String[] args){
                    Track t1 = new Track("Track 1");
                    Track t2 = new Track("Track 2");
                    Gate g = new Gate();
                    t1.simulateTrack();
                    t2.simulateTrack();
                    do{
                        System.out.print("");
                        if((t1.isApproaching() || t1.isCrossing()) || (t2.isApproaching() || t2.isCrossing())){
                            if(!g.isClosed() && !g.isClosing()){
                                g.close();
                            }
                        }else if(g.isClosed() && !g.isOpening()){
                            g.open();
                        }
                    }while((t1.isSimulating() || t2.isSimulating()));


    }
}

还有Track的代码

import java.security.SecureRandom;

public class Track {

    private static final SecureRandom gen = new SecureRandom() ;
    private boolean approaching = false;
    private boolean atCrossing = false;
    private boolean simulating = false;
    private String trackName = "";

    public Track(String n){
        trackName = n;
    }

    public void simulateTrack(){
        Runnable task = new Runnable() {
            public void run() { 
                try { 
                    setSimulating(true);
                    for(int i = 0; i < 10; i++){
                        Thread.sleep((gen.nextInt(5000) + 2500));
                        setApproaching(true);
                        System.out.println(trackName + ": Train is now approaching.");
                        Thread.sleep((gen.nextInt(5000) + 3500));
                        setCrossing(true);
                        setApproaching(false);
                        System.out.println(trackName + ": Train is now crossing.");
                        Thread.sleep((gen.nextInt(1000) + 1000));
                        setCrossing(false);
                        System.out.println(trackName + ": Train has left.");
                    }
                    setSimulating(false);
                } catch (Exception ex) { 

                } 
            } 
        }; 
        new Thread(task, "simulationThread").start(); 
    }

    public boolean isApproaching(){
        return approaching;
    }

    public boolean isCrossing(){
        return atCrossing;
    }

    public boolean isSimulating(){
        return simulating;
    }

    public synchronized void setSimulating(boolean t){
        simulating = t;
    }
    public synchronized void setApproaching(boolean t){
        approaching = t;
    }

    public synchronized void setCrossing(boolean t){
        atCrossing = t;
    }
}

1 个答案:

答案 0 :(得分:1)

这只是一个想法: 通过在后台线程上拍摄close()逻辑,您将失去原子性。 main的{​​{1}}循环可以放弃5次,然后放弃对主线程的控制,其中一个“closeThread”开始执行。你不会看到多个“GATE:Closed”吗?

试试这个(未经测试,抱歉):

do

您需要以相同的方式修改public synchronized void close() { // added synchornized if (!isClosing()) { // read: "if not closing" setClosing(true); // set closing so next time close() is called it is a no op setOpening(false); // close other loopholes so the state is correct System.out.println("GATE: Closing"); // we're in closing state now, because the close method is almost finished // start the actual closing sequence Runnable task = new Runnable() { public void run() { try { Thread.sleep(400); System.out.println("GATE: Closed"); setClosed(true); setClosing(false); }catch(Exception ex){ } } }; new Thread(task, "closeThread").start(); } } ,以便始终保留不变量。检查和设置open()closing标记是互斥的,这就是将opening放在这两个标记上所得到的。