Java 线程,以及为什么我的程序似乎陷入了单一方法的困境
我正在尝试学习一些网络编程,所以我认为一个很好的起点是使用套接字以及如何使用它们。虽然我似乎遇到了麻烦,但问题与插座的关系并不像同时检查插座上的两件事(似乎)那么大Java 线程,以及为什么我的程序似乎陷入了单一方法的困境,java,multithreading,sockets,Java,Multithreading,Sockets,我正在尝试学习一些网络编程,所以我认为一个很好的起点是使用套接字以及如何使用它们。虽然我似乎遇到了麻烦,但问题与插座的关系并不像同时检查插座上的两件事(似乎)那么大 package com.redab.server; import java.io.BufferedReader; import java.io.DataInputStream; import java.io.IOException; import java.io.InputStreamReader; import java
package com.redab.server;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class server implements Runnable {
private final int portNumber = 4444;
private ServerSocket serverSocket;
private Socket clientSocket;
private Thread thread;
private PrintWriter out;
private BufferedReader in;
private BufferedReader stdIn;
private String incomingText;
private String outgoingText;
private Boolean isRunning = false;
public server() {
thread = new Thread(this, "serverThread");
try {
serverSocket = new ServerSocket(portNumber);
clientSocket = serverSocket.accept(); // Unless socket connection is made, probram will not proceed beyond this line.
System.out.println("connected");
out = new PrintWriter(clientSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
stdIn = new BufferedReader(new InputStreamReader(System.in));
} catch (IOException e) {
System.out.println("Exception caught when trying to listen on port " + portNumber + " or listening for a connection");
System.out.println(e.getMessage());
}
}
private synchronized void start() {
thread.start();
isRunning = true;
}
private synchronized void stop() {
try {
thread.join();
isRunning = false;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void run() {
System.out.println("running...");
while (isRunning) {
incoming();
outgoing();
}
}
private synchronized void incoming() {
System.out.println("Incoming");
try {
if ((incomingText = in.readLine()) != null) {
System.out.println(incomingText);
}
} catch (IOException e) {
e.printStackTrace();
}
}
private synchronized void outgoing() {
System.out.println("outgoing");
try {
if ((outgoingText = stdIn.readLine()) != null) {
out.println("Server: " + outgoingText);
System.out.println("Server: " + outgoingText);
}
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
server server = new server();
server.start();
}
}
我的问题如下:
如何使方法incoming()和outing()在执行代码时都能持续运行?
我做了一点谷歌搜索,线程似乎是解决方案,所以我尝试创建一个线程,它应该为我运行这两种方法。但是我又遇到了同样的问题,当我想让代码简单地检查这条语句时,代码卡在incoming()方法中((incomingText=in.readLine())!=null),然后继续执行outing()方法。我怀疑我可能需要两个线程,其中一个线程通过套接字检查传入消息,另一个线程检查在控制台(System.in)
中键入的传出消息
我怀疑我可能需要两个线程,其中一个通过套接字检查传入消息,另一个检查输入控制台(System.in)的传出消息
您是对的,您需要两个线程,每个任务一个。您可能需要先使用.ready()中的
方法检查是否有可读取的数据。如果可用,可以使用.readLine()中的读取数据,否则不执行任何操作。当前,in.readLine()
阻塞,因为套接字上没有可用的输入。如果希望同时接收/传输,则需要两个线程。基于@JimGarrison所说的:程序中的每个线程都应该等待一件事。例如,等待传入网络连接的线程、读取已建立网络连接的线程、等待控制台输入或键盘和鼠标事件的线程,或等待任务的工作线程池线程。虽然为true,但这并不能真正解决OP的问题。如果.ready()
中的为false,您该怎么办?进入一个艰难的投票循环,直到有事情发生?需要两个线程。我试过了,它很有效。如果in.ready()为false,它只需在运行函数时(isRunning)
返回到循环,就像我想要的一样。然而,这并不是说拥有两个线程是个坏主意,我只是还没有弄清楚如何创建线程并使它们完成单独的任务。@JimGarrison,你介意在我实际解决OP的问题时恢复你的否决票吗?不,因为这种方法会导致硬轮询循环,占用100%的cpu。@JimGarrison,如果在.ready()中带有in.ready()
的if语句不执行任何操作(如果为false),它将如何进入硬轮询循环?