【问题标题】:Taking runable class and making it into it's own thread采用可运行类并使其成为自己的线程
【发布时间】:2019-03-31 17:23:19
【问题描述】:

嘿,Java 的所有新手,我确信这很简单,但无法正确获取它以使其正常工作。

这个可运行类的原始java代码:

import java.io.IOException;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ChatServer {
    private static Set < String > names = new HashSet < > ();
    private static Set < PrintWriter > writers = new HashSet < > ();
    public static int thePort = 8877;

    private static boolean isPortInUse(String host, int port) throws SocketException {
        boolean result = false;

        try {
            (new Socket(host, port)).close();
            result = true;

        } catch (IOException e) {
            // Could not connect.
        }

        return result;
    }

    @SuppressWarnings("unused")
    public static void main(String[] args) throws Exception {
        System.out.println("The chat server is running...");
        ExecutorService pool = Executors.newFixedThreadPool(500);
        boolean hasPort = isPortInUse("localhost", thePort);

        try (ServerSocket listener = new ServerSocket(thePort)) {
            while (true) {
                pool.execute(new Handler(listener.accept()));
            }
        }
    }

    private static class Handler implements Runnable {
        private String name;
        private Socket socket;
        private Scanner in ;
        private PrintWriter out;

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

        public void run() {
            try {
                in = new Scanner(socket.getInputStream());
                out = new PrintWriter(socket.getOutputStream(), true);

                while (true) {
                    out.println("SUBMITNAME");
                    name = in .nextLine();

                    if (name == null) {
                        return;
                    }

                    synchronized(names) {
                        if (!name.isEmpty() && !names.contains(name)) {
                            names.add(name);
                            break;
                        }
                    }
                }

                out.println("NAMEACCEPTED " + name);

                for (PrintWriter writer: writers) {
                    writer.println("MESSAGE " + name + " has joined");
                }

                writers.add(out);

                while (true) {
                    String input = in .nextLine();

                    if (input.toLowerCase().startsWith("/quit")) {
                        return;
                    }

                    for (PrintWriter writer: writers) {
                        writer.println("MESSAGE " + name + ": " + input);
                    }
                }
            } catch (Exception e) {
                System.out.println(e);
            } finally {
                if (out != null) {
                    writers.remove(out);
                }

                if (name != null) {
                    System.out.println(name + " has left");
                    names.remove(name);

                    for (PrintWriter writer: writers) {
                        writer.println("MESSAGE " + name + " has left");
                    }
                }
                try {
                    socket.close();
                } catch (IOException e) {}
            }
        }
    }
}

我创建的线程代码是这样的:

static Thread serverThread = new Thread(new Runnable() {
    private String name;
    private Socket socket;
    private Scanner in ;
    private PrintWriter out;

    @Override
    public void run() {
        try {
            Set < String > names = new HashSet < > ();
            Set < PrintWriter > writers = new HashSet < > ();
            int thePort = 8877;

            System.out.println("The chat server is running...");
            ExecutorService pool = Executors.newFixedThreadPool(500);
            boolean hasPort = isPortInUse("localhost", thePort);

            try (ServerSocket listener = new ServerSocket(thePort)) {
                while (true) {
                    pool.execute(new Handler(listener.accept()));
                }
            }
            try {
                in = new Scanner(socket.getInputStream());
                out = new PrintWriter(socket.getOutputStream(), true);

                while (true) {
                    out.println("SUBMITNAME");
                    name = in .nextLine();

                    if (name == null) {
                        return;
                    }

                    synchronized(names) {
                        if (!name.isEmpty() && !names.contains(name)) {
                            names.add(name);
                            break;
                        }
                    }
                }

                out.println("NAMEACCEPTED " + name);

                for (PrintWriter writer: writers) {
                    writer.println("MESSAGE " + name + " has joined");
                }

                writers.add(out);

                while (true) {
                    String input = in .nextLine();

                    if (input.toLowerCase().startsWith("/quit")) {
                        return;
                    }

                    for (PrintWriter writer: writers) {
                        writer.println("MESSAGE " + name + ": " + input);
                    }
                }
            } catch (Exception e) {
                System.out.println(e);
            } finally {
                if (out != null) {
                    writers.remove(out);
                }

                if (name != null) {
                    System.out.println(name + " has left");
                    names.remove(name);

                    for (PrintWriter writer: writers) {
                        writer.println("MESSAGE " + name + " has left");
                    }
                }

                try {
                    socket.close();
                } catch (IOException e) {}
            }
        } catch (Exception e) {
            System.out.println(e);
        }
    }

    public void Handler(Socket socket) {
        this.socket = socket;
    }

    private boolean isPortInUse(String host, int port) throws SocketException {
        boolean result = false;

        try {
            (new Socket(host, port)).close();
            result = true;
        } catch (IOException e) {
            // Could not connect.
        }

        return result;
    }    
});

上面所有代码中我仅有的两个错误是:

处理程序无法解析为类型

pool.execute(new Handler(listener.accept()));

方法的返回类型丢失

public Handler(Socket socket) {

那么我需要更改什么来替换 Handler 以便它可以与我创建的线程代码一起工作?

更新 #1

我同时调用服务器和客户端的主类:

        @SuppressWarnings({ "resource", "unused" })
        private static void placeChatOnScreen() {
            textField = new JTextField();
            textField.setFont(new Font("Segoe UI", Font.PLAIN, 13));
            textField.setDragEnabled(true);
            textField.setBorder(new MatteBorder(1, 1, 1, 1, (Color) new Color(0, 0, 0)));
            textField.setBounds(338, 838, 954, 22);
            frame.getContentPane().add(textField);

            messageArea = new JTextArea();
            messageArea.setEditable(false);
            messageArea.setFont(new Font("Segoe UI", Font.PLAIN, 13));
            messageArea.setBorder(new MatteBorder(1, 1, 1, 1, (Color) new Color(0, 0, 0)));
            messageArea.setDragEnabled(true);
            messageArea.setName("chatArea");
            messageArea.setWrapStyleWord(true);
            messageArea.setBounds(338, 648, 954, 181);
            frame.getContentPane().add(messageArea);

            textField.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    out.println(textField.getText());
                    textField.setText("");
                }
            });

             // start server
            final Thread serverThread = new Thread(new Handler());
            serverThread.start();
            // wait a bit
            Thread.sleep(1000);
            // start client
            clientThread.start();
        }

这是服务器类(正如你所说的那样):

public class ChatServer {
    private static Set<String> names = new HashSet<>();
    private static Set<PrintWriter> writers = new HashSet<>();
    public static int thePort = 8877;

    private static boolean isPortInUse(String host, int port) throws SocketException {
      boolean result = false;

      try {
        (new Socket(host, port)).close();
        result = true;

      }
      catch(IOException e) {
        // Could not connect.
      }

      return result;
    }

    @SuppressWarnings("unused")
    public static void main(String[] args) throws Exception {
        System.out.println("The chat server is running...");
        ExecutorService pool = Executors.newFixedThreadPool(500);
        boolean hasPort = isPortInUse("localhost", thePort);

        try (ServerSocket listener = new ServerSocket(thePort)) {
            while (true) {
                pool.execute(new Handler(listener.accept()));
            }
        }
    }

    public static class Handler implements Runnable {
        private String name;
        private Socket socket;
        private Scanner in;
        private PrintWriter out;

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

        public void run() {
            try {
                in = new Scanner(socket.getInputStream());
                out = new PrintWriter(socket.getOutputStream(), true);

                while (true) {
                    out.println("SUBMITNAME");
                    name = in.nextLine();

                    if (name == null) {
                        return;
                    }

                    synchronized (names) {
                        if (!name.isEmpty() && !names.contains(name)) {
                            names.add(name);
                            break;
                        }
                    }
                }

                out.println("NAMEACCEPTED " + name);

                for (PrintWriter writer : writers) {
                    writer.println("MESSAGE " + name + " has joined");
                }

                writers.add(out);

                while (true) {
                    String input = in.nextLine();

                    if (input.toLowerCase().startsWith("/quit")) {
                        return;
                    }

                    for (PrintWriter writer : writers) {
                        writer.println("MESSAGE " + name + ": " + input);
                    }
                }
            } catch (Exception e) {
                System.out.println(e);
            } finally {
                if (out != null) {
                    writers.remove(out);
                }

                if (name != null) {
                    System.out.println(name + " has left");
                    names.remove(name);

                    for (PrintWriter writer : writers) {
                        writer.println("MESSAGE " + name + " has left");
                    }
                }
                try { socket.close(); } catch (IOException e) {}
            }
        }
    }
}

更新 #2

【问题讨论】:

    标签: java multithreading handler runnable


    【解决方案1】:

    您声明了一个 private 类,其他类无法访问该类

    private static class Handler implements Runnable { ... }
    

    所以,如果它们共享同一个包,只需将其标记为 public 或 package-private(无修饰符)

    public static class Handler implements Runnable { ... }
    

    那么,做

    final Thread serverThread = new Thread(new Handler());
    serverThread.start();
    

    【讨论】:

    • 但我的新线程代码中没有 私有静态类处理程序实现 Runnable { ... }??
    • @StealthRT 误解了,抱歉。您可以重用旧的 Handler 类。查看更新的答案。
    • 对不起@lppEdd - 我还是不明白。在我的线程代码(我的 OP 中的第二块代码)中,我没有 private static class Handler implements Runnable { ... }。那是在我要转移到线程的原始类中。
    • @StealthRT 为什么要复制线程内的所有内容?将 Helper 维护为一个单独的类。
    • Hum... 似乎我现在在 final Thread serverThread = new Thread(new Handler()); 上遇到了同样的错误,而不是在其他地方.
    猜你喜欢
    • 2012-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多