【问题标题】:Two server threads in a while loop blocking each otherwhile循环中的两个服务器线程相互阻塞
【发布时间】:2017-11-15 09:17:10
【问题描述】:

大家。 希望你能帮我解决这个问题: 我有两个线程,负责处理来自客户端的连接。

这是我的代码

ServerSocket loginSocket = new ServerSocket(8000);
ServerSocket fileSocket = new ServerSocket(7000);

while (running) {
  new LoginThread(loginSocket.accept(),loginInormation).start();
  new LoaderThread(fileSocket.accept()).start();
}

当我尝试连接到loginSocket两次时,服务器会阻塞并停止工作,阻塞客户端,但是如果我删除它就不会发生这种情况:

new LoginThread(loginSocket.accept(),loginInormation).start();

我没有收到任何错误消息,那么为什么会发生这种情况,我该如何解决这个问题?

【问题讨论】:

  • loginSocket.accept() 可能正在等待连接?
  • 我调查了这个:stackoverflow.com/questions/10131377/…,我看不出你哪里错了。我认为我们需要更多代码。例如,LoginThreadLoaderThread 中的内容。另外,你确定你没有默默地捕捉异常吗?

标签: java multithreading network-programming


【解决方案1】:

accept() 方法是一种阻塞方法,这意味着您的程序在与loginSocket() 建立连接之前不会继续。

当您创建 LoginThread 时,程序会等待连接来设置对象的第一个参数,并且在建立连接之前不会继续执行。

【讨论】:

    【解决方案2】:

    new LoginThread(loginSocket.accept(),loginInormation).start(); 行包含方法调用loginSocket.accept(),将在创建此线程之前调用。此方法调用将阻塞,直到客户端登录。(另外,第二个线程将被fileSocket.accept() 阻塞)。

    至于解决方案,我会将accept() 调用移至每个线程内部。您需要将套接字传递给线程才能执行此操作。

    【讨论】:

      【解决方案3】:

      在不同的线程中启动fileSocket和登录socket

      package com.ca.training.task.app;
      
      import java.io.IOException;
      import java.net.ServerSocket;
      
      public class App {
      
          public void execute() {
              LoginRunnable loginRunnable = new LoginRunnable();
              loginRunnable.setLoginInformation(new Object());//Login information
      
              FileRunnable fileRunnable = new FileRunnable();//Data for loaded runnable.
              fileRunnable.setParams(new Object());
      
              startLoginThread(loginRunnable);
              startFileThread(fileRunnable);
          }
      
          private static void startLoginThread(LoginRunnable loginRunnable) {
              Thread loginThread = new Thread(loginRunnable);
              loginThread.start();
          }
      
          private static void startFileThread(FileRunnable fileRunnable) {
              Thread loadedThread = new Thread(fileRunnable);
              loadedThread.start();
          }
      
          class LoginRunnable implements Runnable {
      
              private Object loginInformation;
      
              @Override
              public void run() {
                  try {
                      ServerSocket loginSocket = new ServerSocket(8000);
                      loginSocket.accept();
                  } catch (IOException e) {
                      e.printStackTrace();
                  }
              }
      
              public Object getLoginInformation() {
                  return loginInformation;
              }
      
              public void setLoginInformation(Object loginInformation) {
                  this.loginInformation = loginInformation;
              }
          }
      
          class FileRunnable implements Runnable {
      
              private Object params;
      
              @Override
              public void run() {
                  try {
                      ServerSocket fileSocket = new ServerSocket(7000);
                  } catch (IOException e) {
                      e.printStackTrace();
                  }
              }
      
              public Object getParams() {
                  return params;
              }
      
              public void setParams(Object params) {
                  this.params = params;
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-11-15
        • 1970-01-01
        • 1970-01-01
        • 2019-01-06
        • 2014-12-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多