目的:使用单线程重复发送消息给服务器端。程序清单:
1,ServerTest.java 服务器端
2,SendThread.java 客户端发送线程
3,Client.java 客户端封装类
4,MainClient.java 客户端主程序代码
服务器端:
import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.ServerSocket;
import java.net.Socket;public class ServerTest { private ServerSocket serverSocket;
private Socket socket; public ServerTest() {
try {
serverSocket = new ServerSocket(31313);
socket = null;
} catch(IOException ioe) {
ioe.printStackTrace();
}
} private void start() { try { System.out.println("Server start..."); while(true) { socket = serverSocket.accept(); if (socket != null) { ObjectInputStream ois = new ObjectInputStream(socket.getInputStream()); Object obj = null; while ((obj = ois.readObject()) != null) {
System.out.println("Context: " + obj.toString());
}
}
} } catch (Exception e) {
e.printStackTrace();
}
} /**
* @param args
*/
public static void main(String[] args) { ServerTest serverTest = new ServerTest();
serverTest.start();
}}客户端发送线程:
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;public class SendThread extends Thread { private ObjectOutputStream oos;
private Serializable message; public SendThread(ObjectOutputStream oos) {
this.oos = oos;
} public void setMessage(Serializable message) {
this.message = message;
} public void run() { while(true) {
if (this.message != null) {
synchronized(this.message) {
try {
oos.writeObject(this.message);
oos.flush();
} catch (IOException ioe) {
ioe.printStackTrace();
} finally {
this.message = null;
}
}
}
}
}
}客户端封装类:
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;import client.thread.SendThread;public class Client { private Socket socket;
private SendThread sendThread;
private ObjectOutputStream oos; public Client() { try { InetAddress inetAddress = InetAddress.getLocalHost();
socket = new Socket("127.0.0.1", 31313, inetAddress, 51515);
oos = new ObjectOutputStream(socket.getOutputStream());
sendThread = new SendThread(oos);
sendThread.start(); } catch (UnknownHostException uhe) {
uhe.printStackTrace();
} catch (IOException ioe) {
ioe.printStackTrace();
}
} public void send(Serializable message) {
System.out.println("send message...");
this.sendThread.setMessage(message);
}
}客户端主程序:
import bean.TestBean;
import client.Client;public class MainClient { public static void main(String[] args) { Client client = new Client(); for (int i = 0; i < 5; i++) {
client.send(new TestBean());// try {
// client.send(new TestBean());
// Thread.sleep(10000);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
}
}
}问题:在客户端主程序中如果不使用sleep方法的话,服务器端只打印一次消息。如果客户端主程序使用了sleep方法(注释部分代码)的话,服务器端可以打印5次消息。不知道是不是由于将消息发送放在一个线程里面,才产生了这种效果,还望各位指教。先谢谢了。
1,ServerTest.java 服务器端
2,SendThread.java 客户端发送线程
3,Client.java 客户端封装类
4,MainClient.java 客户端主程序代码
服务器端:
import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.ServerSocket;
import java.net.Socket;public class ServerTest { private ServerSocket serverSocket;
private Socket socket; public ServerTest() {
try {
serverSocket = new ServerSocket(31313);
socket = null;
} catch(IOException ioe) {
ioe.printStackTrace();
}
} private void start() { try { System.out.println("Server start..."); while(true) { socket = serverSocket.accept(); if (socket != null) { ObjectInputStream ois = new ObjectInputStream(socket.getInputStream()); Object obj = null; while ((obj = ois.readObject()) != null) {
System.out.println("Context: " + obj.toString());
}
}
} } catch (Exception e) {
e.printStackTrace();
}
} /**
* @param args
*/
public static void main(String[] args) { ServerTest serverTest = new ServerTest();
serverTest.start();
}}客户端发送线程:
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;public class SendThread extends Thread { private ObjectOutputStream oos;
private Serializable message; public SendThread(ObjectOutputStream oos) {
this.oos = oos;
} public void setMessage(Serializable message) {
this.message = message;
} public void run() { while(true) {
if (this.message != null) {
synchronized(this.message) {
try {
oos.writeObject(this.message);
oos.flush();
} catch (IOException ioe) {
ioe.printStackTrace();
} finally {
this.message = null;
}
}
}
}
}
}客户端封装类:
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;import client.thread.SendThread;public class Client { private Socket socket;
private SendThread sendThread;
private ObjectOutputStream oos; public Client() { try { InetAddress inetAddress = InetAddress.getLocalHost();
socket = new Socket("127.0.0.1", 31313, inetAddress, 51515);
oos = new ObjectOutputStream(socket.getOutputStream());
sendThread = new SendThread(oos);
sendThread.start(); } catch (UnknownHostException uhe) {
uhe.printStackTrace();
} catch (IOException ioe) {
ioe.printStackTrace();
}
} public void send(Serializable message) {
System.out.println("send message...");
this.sendThread.setMessage(message);
}
}客户端主程序:
import bean.TestBean;
import client.Client;public class MainClient { public static void main(String[] args) { Client client = new Client(); for (int i = 0; i < 5; i++) {
client.send(new TestBean());// try {
// client.send(new TestBean());
// Thread.sleep(10000);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
}
}
}问题:在客户端主程序中如果不使用sleep方法的话,服务器端只打印一次消息。如果客户端主程序使用了sleep方法(注释部分代码)的话,服务器端可以打印5次消息。不知道是不是由于将消息发送放在一个线程里面,才产生了这种效果,还望各位指教。先谢谢了。
而如果sleep一下的话,会保证每一次while发送完消息,将消息清空后,主线程睡醒后再次修改message的值,触发线程再次发消息.
client.send(new TestBean());
}
你在这个循环里执行的语句是不断的改变client里面的线程对象的message属性
而这个线程对象里面监听message属性改变就会发送信息并重新赋值为null但是你这里运行的是主线程和client里面的线程对象是两个线程。
对于cpu来说main线程执行 i=0~5这5次循环是瞬间,
在这时间片里面client里面的SendThread线程对象很少能有机会获得执行时间。
也就是说等你main做完了5次循环,SendThread才会执行,监听message属性的改变并向服务器端发送请求。如果你在循环中每次赋值main线程都小sleep下,sendThread就会拿到时间片去执行,判断出message改变并发送请求,就能成功发送5次。