对于我所看到的问题的冗长描述感到抱歉。
我有下面记录的代码,我一直试图让它使用线程不按顺序发送消息。我继续在客户端上获得以下控制台输出。
回显客户端消息:您好:0 14210577 14210579
回显客户端消息:您好:1 14211379 14211379
回显客户端消息:您好:2 14212181 14212181
回显客户端消息:您好:3 14212981 14212982
回显客户留言:您好:4 14213782 14213782
回显客户端消息:您好:5 14214582 14214583
回显客户留言:您好:6 14215383 14215383
回显客户端消息:您好:7 14216184 14216184
回显客户端消息:您好:8 14216984 14216984
回显客户留言:您好:9 14217785 14217785
我希望实现的客户端上的控制台输出类似于以下内容(消息2之后的所有消息都在消息2之前发送)
回显客户端消息:您好:0 14210577 14210579
回显客户端消息:您好:1 14211379 14211379
回显客户端消息:您好:3 14212981 14212982
回显客户留言:您好:4 14213782 14213782
回显客户端消息:您好:5 14214582 14214583
回显客户留言:您好:6 14215383 14215383
回显客户端消息:您好:7 14216184 14216184
回显客户端消息:您好:8 14216984 14216984
回显客户留言:您好:9 14217785 14217785
回显客户留言:您好:2 14212181 14217885
客户端上的控制台输出具有以下内容:我可以看到,在消息2完成其等待时间之前,不会发送服务器对消息3的响应。我希望服务器在消息2完成等待之前将其响应发送到消息3。
传入客户端消息:您好:2 15430652
在ServerThread中调用Send Message:15430653
从ServerThread中的发送消息返回:15430653
sendMessage.doWork()中的:15430653
sendMessage.doWork()完成等待:15430753
传入客户端消息:您好:3 15430753
如何让线程继续处理其他消息而不必等待消息2等待完成?
提前感谢任何输入。
服务器类:
// Built off the following tutorials
// https://www.youtube.com/watch?v=2cQJJwoSNLk
// https://www.youtube.com/watch?v=nCIw0h1C8Qo
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.TimeUnit;
public class Server{
public static void main(String[] args) {
try {
new Server().runServer();
} catch (IOException e) {
e.printStackTrace();
}
}
public void runServer() throws IOException{
final int PORT = 4444;
ServerSocket serverSocket = new ServerSocket(PORT);
System.out.println(new StringBuilder().append("Server up and ready for connections...").toString());
while(true){
Socket socket = serverSocket.accept();
new Thread(new ServerThread(socket)).start();
}
}
public class ServerThread implements Runnable{
private Socket socket;
private String message;
ServerThread(Socket socket){
this.socket = socket;
}
public void run(){
try {
this.message = null;
PrintWriter printWriter = new PrintWriter(socket.getOutputStream(),true);
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader (socket.getInputStream()));
while((message = bufferedReader.readLine()) != null){
System.out.println(new StringBuilder().append("incoming client message: ").append(message).toString());
long sendTime = System.nanoTime();
if(message.trim().startsWith("Hello: 2")){
sendTime = System.nanoTime() + 100000000;
}
System.out.println(new StringBuilder().append("calling Send Message in ServerThread: ").append(" ").append(TimeUnit.NANOSECONDS.toMillis(System.nanoTime())).toString());
new Thread(
new SendMessage(printWriter,
sendTime,
new StringBuilder().append("echoing client message: ").append(message).append(" ").append(TimeUnit.NANOSECONDS.toMillis(System.nanoTime())).toString()
)
).start();
System.out.println(new StringBuilder().append("returned from Send Message in ServerThread: ").append(" ").append(TimeUnit.NANOSECONDS.toMillis(System.nanoTime())).toString());
}
} catch (IOException e) {
}
}
}
}
客户类:
// Built off the following tutorials
// https://www.youtube.com/watch?v=2cQJJwoSNLk
// https://www.youtube.com/watch?v=nCIw0h1C8Qo
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.concurrent.TimeUnit;
public class Client {
public static final int PORT = 4444;
public static void main(String[] args) throws UnknownHostException, IOException {
Socket socket = new Socket("localhost",PORT);
PrintWriter printWriter = new PrintWriter(socket.getOutputStream(),true);
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
for(int x = 0; x<10;x++){
if(x==5){
printWriter.println(new StringBuilder().append("Hello: ").append(x).append(" ").append(TimeUnit.NANOSECONDS.toMillis(System.nanoTime())).toString());
}else{
printWriter.println(new StringBuilder().append("Hello: ").append(x).append(" ").append(TimeUnit.NANOSECONDS.toMillis(System.nanoTime())).toString());
}
System.out.println(new StringBuilder().append(bufferedReader.readLine()));
}
//socket.close();
}
}
SendMessage类:
import java.io.PrintWriter;
import java.util.concurrent.TimeUnit;
public class SendMessage implements Runnable{
private PrintWriter printWriter;
private Long SendTimeInNanos;
private String message;
public SendMessage(PrintWriter printWriter, Long SendTimeInNanos, String message){
this.printWriter = printWriter;
this.SendTimeInNanos = SendTimeInNanos;
this.message = message;
}
@Override
public void run() {
doWork();
}
private void doWork(){
System.out.println(new StringBuilder().append("in sendMessage.doWork(): ").append(" ").append(TimeUnit.NANOSECONDS.toMillis(System.nanoTime())).toString());
//sleep until the appropriate time
while(this.SendTimeInNanos > System.nanoTime()){
try {
//sleep until appropriate time
Thread.sleep(TimeUnit.NANOSECONDS.toMillis(this.SendTimeInNanos-System.nanoTime()));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println(new StringBuilder().append("sendMessage.doWork() done waiting: ").append(" ").append(TimeUnit.NANOSECONDS.toMillis(System.nanoTime())).toString());
//send at appropriate time
this.printWriter.println(new StringBuilder().append(this.message).toString());
}
}
答案 0 :(得分:0)
总体而言,您的代码看起来不错。问题可能在于您创建和启动线程的方式:
while(true){
Socket socket = serverSocket.accept();
new Thread(new ServerThread(socket)).start();
}
看起来每个新线程在创建新线程之前都会很快完成执行。要实现异步线程执行,请尝试创建多个ServerThread
实例并立即启动所有实例:
while(true){
Socket socket = serverSocket.accept();
List<Thread> threads = new ArrayList<>();
for (int i = 0; i < 4; i++)
{
threads.add(new Thread(new ServerThread(socket)));
}
threads.forEach(Thread::start);
}