为什么此代码仅在带有断点的调试模式下有效? (IDE调试器)

时间:2017-08-28 11:57:25

标签: java eclipse sockets debugging telnet

您好我正在写一个简单的telnet(后来我将有一个自定义的telnet客户端解释命令)命令和控制服务器在纯java 我有一些代码只有当我在调试器和断点正确的地方才有效这很奇怪

代码:

主:

package LiteDoor;

import java.io.File;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;

import LiteDoor.net.AcceptTelnetClient;

public class Main {

    public static final String VERSION = "v0.0.1"; 

    public static File scripts = new File("scripts");

    public static ArrayList<AcceptTelnetClient> conns = new ArrayList<AcceptTelnetClient>();

    public static void main(String args[]) throws Exception
    {
        File autorun = new File(scripts.getAbsolutePath()+File.separatorChar+"autorun.litescript");
        if (!autorun.exists()) {
            scripts.mkdirs();
            autorun.createNewFile();
        }

        ServerSocket Soc=new ServerSocket(666);
        while(true)
        {
            Socket CSoc=Soc.accept();
            AcceptTelnetClient ob=new AcceptTelnetClient(CSoc);
        }
    }

}

AcceptTelnetClient:

package LiteDoor.net;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;

import LiteDoor.Main;
import LiteDoor.io.MyBufferedWriter;

public class AcceptTelnetClient extends Thread {
    Socket ClientSocket;
    public boolean master;
    public String slaveCmd = null;

    public AcceptTelnetClient(Socket CSoc) throws Exception {
        Main.conns.add(this);

        ClientSocket=CSoc;
        System.out.println("Client Connected ...");
        BufferedReader in  = new BufferedReader(new InputStreamReader(ClientSocket.getInputStream()));
        @SuppressWarnings("resource")
        MyBufferedWriter out = new MyBufferedWriter(new OutputStreamWriter(ClientSocket.getOutputStream()));  

        out.writeln("MASTER/SLAVE?");

        switch(in.readLine().toUpperCase()) {
        case("MASTER"):
            master = true;
            break;
        case("SLAVE"):
            master = false;
            break;
        }

        int i=0;
        while(i<200) {
            out.newLine();
            i++;
        }
        out.flush();

        start();        
    }

    public void run() {
        try {    
            BufferedReader in=new BufferedReader(new InputStreamReader(ClientSocket.getInputStream()));
            @SuppressWarnings("resource")
            MyBufferedWriter out = new MyBufferedWriter(new OutputStreamWriter(ClientSocket.getOutputStream()));  

            out.writeln("");

            if (!master) {
                BufferedReader fr = new BufferedReader(new FileReader(Main.scripts.getAbsolutePath()+File.separatorChar+"autorun.litescript"));
                String line = fr.readLine();
                while(line != null) {
                    if (!line.startsWith("#") && line != "") {
                        out.writeln(line);
                    }
                    line = fr.readLine();
                }
                fr.close();
            }

            boolean loop = true;

            while(loop) {
                if (master) {
                    String cmd = in.readLine();
                    if(cmd.startsWith("quit")) {

                        loop=false;

                    } else {  
                        System.out.println("Master says: " + cmd);
                        for (AcceptTelnetClient con : Main.conns) {
                            if (!con.master) {
                                synchronized (con) {
                                    con.slaveCmd = cmd;
                                }
                            }
                        }
                    }
                } else {
                    if (slaveCmd != null) {
                        synchronized (this) { // Here needs to be an breakpoint
                            out.writeln(slaveCmd);
                            slaveCmd = null;
                        }
                    }
                }
            }
            ClientSocket.close();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                ClientSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    } 
}

发生了什么:

客户端1连接到&#34; slave&#34;中的服务器类型。 并等待一些命令被发送给它

客户端2连接&#34; master&#34;中的类型。并发送一些命令 然后shloud被发送给所有连接的用户&#34; slave&#34;

会发生什么: 客户端1作为从属连接 客户端2连接为主发送命令但奴隶没有得到它(它没有在telnet客户端窗口中显示)

代码仅在调试器中正常工作,并且在正确的位置使用断点

PS是的,我试过谷歌搜索但没有找到任何东西

1 个答案:

答案 0 :(得分:1)

TL; DR ...

你无法确定正在运行的线程是否获得了boolean flag master的更新值,而是声明了volatile ...

 public volatile boolean master;