为什么这段代码只能在带有断点的调试模式下工作? (IDE 调试器)
Why this code works only in debug mode with a breakpoint? (IDE Debugger)
你好,我正在编写一个简单的 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);
}
}
}
接受TelnetClient:
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 连接到 "slave" 中的服务器类型
并等待一些命令发送给它
客户端 2 连接 "master" 中的类型并发送一些命令
然后 shloud 被发送到所有连接为 "slave"
的客户端
发生了什么:
客户端 1 作为从属连接
客户端 2 连接,因为主服务器发送命令但从服务器没有收到它(它没有显示在 telnet 客户端 window)
代码只能在调试器中正常运行,并且断点位于正确的位置
PS 是的,我尝试谷歌搜索但什么也没找到
TL;DR...
您不能确定 运行 线程获得了布尔标志 master 的更新值,改为声明 volatile...
public volatile boolean master;
你好,我正在编写一个简单的 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);
}
}
}
接受TelnetClient:
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 连接到 "slave" 中的服务器类型 并等待一些命令发送给它
客户端 2 连接 "master" 中的类型并发送一些命令 然后 shloud 被发送到所有连接为 "slave"
的客户端发生了什么: 客户端 1 作为从属连接 客户端 2 连接,因为主服务器发送命令但从服务器没有收到它(它没有显示在 telnet 客户端 window)
代码只能在调试器中正常运行,并且断点位于正确的位置
PS 是的,我尝试谷歌搜索但什么也没找到
TL;DR...
您不能确定 运行 线程获得了布尔标志 master 的更新值,改为声明 volatile...
public volatile boolean master;