【问题标题】:Condition to control multithreading connection控制多线程连接的条件
【发布时间】:2015-12-05 15:17:18
【问题描述】:

我在一个服务器和两个客户端之间实现了多线程连接,但是当我启动我的程序时,服务器启动了一个无限循环。这是一个问题,因为我的服务器还实现了一个无法运行的图形界面,因为它被这个循环阻塞了。我想补救,选择不同的条件来停止我的周期,而不是使用while(true)cycle。 这是我的循环代码:

public Socket attendi(){
    try {
       System.out.println("inizializzo il server");
       ss = new ServerSocket(PORT);
       while(true){
           System.out.println("server pronto in ascolto");
           s = ss.accept(); //s is a global Socket object
           ThreadServer newConnection = new ThreadServer();
           newConnection.connect(s);
           System.out.println("connessione stabilita");
       }


    } catch (IOException ex) {
       Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
    }
   return s;
}

您能否推荐一个在没有更多客户端尝试连接到服务器时停止循环的良好条件?

【问题讨论】:

    标签: java multithreading sockets loops


    【解决方案1】:

    启动一个新线程并将这个逻辑放在新线程中,这样你的主线程就不会被阻塞。

    这样,您的主线程将简单地启动一个新线程并继续执行进一步的程序。并且新线程将执行您想做的任何事情(在您的情况下进行一些阻塞操作),而不会阻塞主线程。

    您也可以使用 Java 在 ExecutorService 中的构建。您无需返回s,因为它是全局变量。见以下代码:

    ExecutorService executorService = Executors.newFixedThreadPool(1);
    
    executorService.execute(new Runnable() {
        public void run() {
            try {
           System.out.println("inizializzo il server");
           ss = new ServerSocket(PORT);
           while(true){
               System.out.println("server pronto in ascolto");
               s = ss.accept(); //s is a global Socket object
               ThreadServer newConnection = new ThreadServer();
               newConnection.connect(s);
               System.out.println("connessione stabilita");
           }
        } catch (IOException ex) {
           Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
        }
        }
    });
    
    //Now program execution will continue and the new thread created will execute the logic you have placed in `run` method.
    

    【讨论】:

    • 这会启动一个新线程,但是当窗口关闭时你仍然可能会遇到一个卡住的线程。
    • 没问题。但最后你实施了哪个解决方案,这个还是来自 andy 的答案?
    【解决方案2】:

    首先,您需要扩展Runnable

    public class MyRunnable extends Runnable {
    
        public void run(){
            try {
               System.out.println("inizializzo il server");
               ss = new ServerSocket(PORT);
               while(true){
                   System.out.println("server pronto in ascolto");
                   s = ss.accept(); //s is a global Socket object
                   ThreadServer newConnection = new ThreadServer();
                   newConnection.connect(s);
                   System.out.println("connessione stabilita");
    
                   handleConnection(s);
               }
            } catch (IOException ex) {
               Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }
    

    然后实现一个守护线程工厂。守护线程不会阻止应用程序终止:

    public class DaemonThreadFactory implements ThreadFactory {
        private ThreadFactory threadFactory = Executors.defaultThreadFactory();
    
        public Thread newThread( Runnable runnable ) {
            Thread thread = threadFactory.newThread(runnable);
            thread.setDaemon(true);
            return thread;
        }
    }
    

    然后使用线程工厂创建线程:

    ThreadFactory factory = new DaemonThreadFactory();
    Thread thread = factory.newThread( new MyRunnable() );
    thread.start();
    

    根据提供的代码和描述,在我看来,您实际上并没有在单独的线程中运行它。

    【讨论】:

    • 这样,当我关闭窗口时,我的循环就会停止,对吧?但我的问题是窗口都没有打开
    • 啊,我的误会。这有帮助吗? :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-15
    • 2023-03-04
    • 1970-01-01
    • 2018-12-17
    • 1970-01-01
    • 1970-01-01
    • 2023-03-09
    相关资源
    最近更新 更多