首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用简单服务器进行并发编程

使用简单服务器进行并发编程
EN

Code Review用户
提问于 2012-01-08 22:31:17
回答 3查看 8.5K关注 0票数 12

我正在创建一个简单的服务器,它接受一个int并返回两次接收到的值:

代码语言:javascript
复制
public class MyServer{

    private static int port = 1234;

    public static void main(String args[]){
        try{
            ServerSocket serversock=new ServerSocket(port);
            while(true){
                Socket  socket=serversock.accept();
                new Thread(new MyClass(socket)).start();
            }
        }catch(IOException e){}
        }
    }

    class MyClass implements Runnable{

        Socket socket;

        public MyClass(Socket s){socket = s;}

        public void run(){
            try{
                DataInputStream in = new DataInputStream(socket.getInputStream());
                DataOutputStream out = new DataOutputStream(socket.getOutputStream());
                int x = in.readInt();
                out.write(2*x);
                socket.close();
            }
            catch(IOException e){}
    }
}

我的问题是重新设计代码。这个设计有什么缺点吗?如果是,那么哪些更改将使代码更好?

EN

回答 3

Code Review用户

回答已采纳

发布于 2012-01-08 22:49:52

如果您真的计划为每个传入请求创建一个线程,只需使用和Executors.newCachedThreadPool()即可。只要传入的请求不经常出现,这个ExecutorService就会在您向它提交时创建一个新线程,但是如果一个线程处于空闲状态而没有被使用,服务将重用该线程而不是创建一个新线程。

编辑:下面是使用您的代码的示例。

代码语言:javascript
复制
public class MyServer{

    private static int port = 1234;


    public static void main(String args[]){
        try{
            final ExecutorService service = Executors.newCachedThreadPool();
            ServerSocket serversock=new ServerSocket(port);
            while(true){
                Socket  socket=serversock.accept();
                service.submit(new MyClass(socket));
            }
        }catch(IOException e){}
        }
    }

    class MyClass implements Runnable{

        Socket socket;

        public MyClass(Socket s){socket = s;}

        public void run(){
            try{
                DataInputStream in = new DataInputStream(socket.getInputStream());
                DataOutputStream out = new DataOutputStream(socket.getOutputStream());
                int x = in.readInt();
                out.write(2*x);
                socket.close();
            }
            catch(IOException e){}
    }
}

有了这个,您就有了线程重用的可能性。

票数 8
EN

Code Review用户

发布于 2012-01-08 22:38:27

最突出的是你在默默地忽略那些例外.您至少应该进行一些清理并关闭套接字。

在性能方面,您正在启动一个新线程来执行一个非常小的任务,从而浪费了启动线程的大量时间。您可以将Runnables提交给ExecutorService,条件是从客户端接收数字不依赖于用户输入(否则,如果前几个客户端没有发送任何内容,您将阻塞线程池)。

票数 6
EN

Code Review用户

发布于 2012-01-08 23:49:41

除了都铎氏响应之外,您还不应该编写无限循环--这太愚蠢了。对于打算运行时间未知的服务器(可能是无休止的),我会这样做。

代码语言:javascript
复制
while (keepServerRunning) {   // where 'keepServerRunning' is a simple boolean variable
  ...

然后,...and使用停机钩将值设置为false,该值允许服务器(和JVM)正常退出,而不必通过kill -9或强制关闭来终止任务。

虽然理论上服务可能永远运行,但假装在现实中出现这种情况并不是很好的做法。清理自己,并提供您的应用程序一种简单,干净的方式,以正常退出,只要可能。

票数 6
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/7609

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档