java socket多线程客户端实践
1. 监视线程,负责监视客户端socket连接
2.socket接受线程,负责与客户端数据交流
3.重写ThreadPoolExecutor类,实现查看当前正在运行的线程
package com.jike.java_base;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.*;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* @program: jike_study
* @description:
* @author: dyingstraw
* @create: 2019-03-19 14:56
**/
public class SocketTest extends Thread{
private String address="127.0.0.1";
private int port = 8888;
// 线程池的阻塞队列
private ArrayBlockingQueue<Runnable> queue=new ArrayBlockingQueue<Runnable>(15);
// 为socket创建线程池
ThreadPoolExecutor poolExecutor = new selfPool(
10,15,50,
TimeUnit.SECONDS,queue);
public SocketTest(String address, int port) {
this.address = address;
this.port = port;
}
public String getAddress() {
return address;
}
public int getPort() {
return port;
}
// 重新线程池,获得自己的线程池实现
class selfPool extends ThreadPoolExecutor{
public ArrayList<Runnable> workList = new ArrayList<>();
// 获得正在工作的线程
public ArrayList<Runnable> getWorkList() {
return workList;
}
public selfPool(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
}
@Override
protected void beforeExecute(Thread t, Runnable r) {
super.beforeExecute(t, r);
workList.add(r);
}
@Override
protected void afterExecute(Runnable r, Throwable t) {
super.afterExecute(r, t);
workList.remove(r);
}
}
// 消息链接线程
class SocketThread implements Runnable{
private Queue<String> messageQueue = new PriorityQueue<>();
private Socket socket;
private String sessionId;
private OutputStream o;
public SocketThread(Socket socket,String sessionId) throws IOException {
this.socket = socket;
this.sessionId = sessionId;
this.o = socket.getOutputStream();
System.out.println(o);
}
// 获取sessionId
public String getSessionId() {
return sessionId;
}
// 获得消息监听
public void onMessage(String message){
System.out.println(message);
}
// 线程关闭监听
public void onClosed(Socket socket){
System.out.println("onClosed");
}
// 关闭线程
public void close(){
Thread.currentThread().interrupt();
}
// socket发送
public boolean send(String s){
System.out.println(o);
try {
o.write(s.getBytes());
o.flush();
} catch (IOException e) {
e.printStackTrace();
return false;
}
return true;
}
@Override
public void run() {
try {
InputStream in = null;
// 得到输入流
in = socket.getInputStream();
System.out.println("connect from:"+socket.getLocalAddress() +":" + socket.getPort());
while (true){
// 读取客户端发来的信息
if (in.available()>0){
byte[] buff = new byte[in.available()];
in.read(buff);
onMessage(buff.toString());
}
// 接受外部interrupted指令,退出线程
if (Thread.currentThread().isInterrupted()){
throw new Exception("SocketThread is dead!");
}
// 查询是否和客户端断开通讯
if (in.read()==-1){
throw new Exception("Socket closed!");
}
}
}catch (IOException e){
e.printStackTrace();
return;
}
catch (Exception e) {
e.printStackTrace();
}
}
}
@Override
public void run() {
try {
server();
} catch (IOException e) {
e.printStackTrace();
}
}
// 监听socket连接
public void server() throws IOException {
ServerSocket ssocket = new ServerSocket();
// 绑定端口
ssocket.bind(new InetSocketAddress(this.getPort()));
while (true){
Socket socket = ssocket.accept();
if (socket!=null){
// 把新进的socket放入线程池,标识随意
SocketThread r = new SocketThread(socket, String.valueOf(socket.getPort()));
poolExecutor.execute(r);
}
}
}
public static void main(String[] args) throws IOException {
SocketTest socketTest = new SocketTest("127.0.0.1",8888);
// 启动监听线程
socketTest.start();
//启动交互线程
Thread t = new Thread(){
@Override
public void run() {
while (true){
Scanner scanner = new Scanner(System.in);
String sid = scanner.nextLine();
System.out.println(sid);
Iterator<Runnable> it = ((selfPool) (socketTest.poolExecutor)).getWorkList().iterator();
while (it.hasNext()){
SocketThread temp = (SocketThread) it.next();
System.out.println(temp.sessionId);
if (temp.sessionId.equals(sid)){
temp.send("6666666666666666666");
}
}
}
}
};
t.start();
}
}