首页 > 编程语言 >java网络编程-并发服务端

java网络编程-并发服务端

时间:2023-02-28 10:12:30浏览次数:34  
标签:java socket 编程 线程 new 客户端 服务端 Socket

上次的服务端一次只能接受一个客户端的连接,性能实在堪忧,我们对服务端进行了改造,

每接到一个客户端的请求,就新建一个线程,让新线程跟客户端进行交互,主线程可以继续等待其他客户端的连接。

服务端:

public class Server {
    public static void main(String[] args) throws Exception {
        System.out.println("==服务器的启动==");
        // 1.注册端口
        ServerSocket serverSocket = new ServerSocket(8888);
        while (true) {
        //2.每接收到客户端的连接,就新建一个线程进行处理
            Socket socket = serverSocket.accept();
            new ServerReadThread(socket).start();
            System.out.println(socket.getRemoteSocketAddress() + "上线!");
        }
    }

    static class ServerReadThread extends Thread {
        private Socket socket;

        public ServerReadThread(Socket socket) {
            this.socket = socket;
        }

        @Override
        public void run() {
            try {
                InputStream is = socket.getInputStream();
                //4.把字节输入流包装成自己需要的流进行数据的读取。
                BufferedReader br = new BufferedReader(new InputStreamReader(is));
                //5.循环读取数据并打印到屏幕
                String line;
                while ((line = br.readLine()) != null) {
                    System.out.println("收到:" + line);
                }
            } catch (IOException e) {
                System.out.println(socket.getRemoteSocketAddress() + "下线!");
                throw new RuntimeException(e);
            }
        }
    }
}

客户端代码不变:

public class Client {
    public static void main(String[] args) throws Exception {
        System.out.println("==客户端的启动==");
        // 1.创建一个Socket的通信管道,请求与服务端的端口连接。
        Socket socket = new Socket("127.0.0.1", 8888);
        // 2.从Socket通信管道中得到一个字节输出流。
        OutputStream os = socket.getOutputStream();
        // 3.把字节流改装成自己需要的流进行数据的发送
        PrintStream ps = new PrintStream(os);
        // 4.开始发送消息
        Scanner sc = new Scanner(System.in);
        while (sc.hasNextLine()) {
            String msg = sc.nextLine();
            ps.println(msg);
            ps.flush();
        }
    }
}

虽然解决了一些问题,但还有一些不完美

1.每个Socket接收到,都会创建一个线程,线程的竞争、切换上下文影响性能;
2.每个线程都会占用栈空间和CPU资源;
3.并不是每个socket都进行IO操作,无意义的线程处理;
4.客户端的并发访问增加时。服务端将呈现1:1的线程开销,访问量越大,系统将发生线程栈溢出,线程创建失
败,最终导致进程宕机或者僵死,从而不能对外提供服务

标签:java,socket,编程,线程,new,客户端,服务端,Socket
From: https://www.cnblogs.com/wangbin2188/p/17162956.html

相关文章

  • java面试题-列举常见的异常
    面试中经常会被问到,列举几种常见异常。怎么能被这个难倒呢?下面随便列举些,以及触发例子。文章目录​​NullPointerException​​​​ArithmeticException​​​​NumberFor......
  • java使用gzip压缩和解压
    代码如下:publicclassGZipUtils{publicstaticfinalintBUFFER=1024;publicstaticfinalStringEXT=".gz";publicstaticvoidmain(String[]args)......
  • java使用commons-lang3
    pom.xml中添加<!--https://mvnrepository.com/artifact/org.apache.commons/commons-lang3--><dependency><groupId>org.apache.commons</groupId><artifactId>co......
  • java常用系统属性System.getProperties().getProperty()
    用法例子:System.out.println(System.getProperties().getProperty("user.home"));常用属性列表:属性含义java.versionJava运行时环境版本java.vendorJava运行时环境供应商jav......
  • java8 flatmap的使用
    Useruser=newUser(“[email protected]”,“1234”);user.setPosition(“Developer”);Stringposition=Optional.ofNullable(user).flatMap(u->u.getPosition()).......
  • java中输出方框(未知字符)
    这说明是空白字符,注意不是空字符串,也不是null。他是unicode中的\u0000也就是NULL.哪些场景会出现该情况?char数组中有未设定的字符,会当做空白字符来打印publicstaticvo......
  • java使用nio多线程读文件
    模拟多线程nio读取文件,并输出,output方法自己补一下。ReadFile代码:publicclassReadFileextendsObservable{privateintbufSize=1024;//换行符privateb......
  • java-jdbc
    0、简介Java数据库连接,(JavaDatabaseConnectivity,简称JDBC)是Java语言中用来规范客户端程序如何来访问数据库的应用程序接口,提供了诸如查询和更新数据库中数据的方法。J......
  • java网络编程-客户端和服务器
    基于java.net包,实现一个简单的服务端和客户端,客户端只管发,服务端只管收缺点:服务端只能处理一个客户端的请求,因为服务端是单线程的。一次只能与一个客户端进行消息通信服......
  • Failed to start bean ‘documentationPluginsBootstrapper’; nested exception is j
    Youmightencounterthe“Failedtostartbean'documentationPluginsBootstrapper';nestedexceptionisjava.lang.NullPointerException”errorwhileupgradingS......