【问题标题】:Java: Sharing and calling variables between threadsJava:在线程之间共享和调用变量
【发布时间】:2019-01-28 07:01:28
【问题描述】:

我使用套接字制作了一个基本服务器,并想添加一个简单的 GUI 来打开和关闭它。为了在服务器运行 while 循环时使 GUI 仍然工作,我为套接字创建了一个线程。现在我想的是在那个退出循环的while循环中添加一个布尔值,并在按下GUI中的按钮时导致服务器停止。

现在的问题是布尔值是在GUI线程中设置的,需要在服务器线程中调用。我阅读了有关将布尔值设置为 volatile 或使用 AtomicBoolean 的信息,但它们似乎都不起作用。从服务器线程调用布尔值时,我可能需要寻找一些特别的东西吗?

这是我目前写的(简化的)代码:

public class GUI {

    private static int port = 12345;    
    private static volatile boolean online = false;     

    public static void main(String[] args) {

        //GUI works so i left the code out
        //Basically generates a button giving it the actionlistener below

    }

    private static ActionListener getActionListener() {

        return new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {

                if(!online) {
                    online = true;

                    Thread serverThread = new Thread(new ServerThread());
                    serverThread.start();

                } else {
                    online = false;                 
                }               
            }
        };
    }

    public static boolean getOnlineState() {
        return online;
    }

    public static int getPort() {
        return port;
    }
}

以及包含服务器线程的类:

public class ServerThread implements Runnable {

    @Override
    public void run() {

        try {
            ServerSocket serSoc = new ServerSocket(GUI.getPort());
            Socket cliSoc = serSoc.accept();
            PrintWriter  out = new PrintWriter(cliSoc.getOutputStream(), true);
            BufferedReader in = new BufferedReader(new    InputStreamReader(cliSoc.getInputStream()));

            String input;
            while(GUI.getOnlineState()) {
                while((input = in.readLine()) != null) {
                    out.println(input);
                }
            }

            out.println("Stopping");
            cliSoc.shutdownInput();
            cliSoc.shutdownOutput();
            cliSoc.close();         
            serSoc.close();
            out.close();
            in.close();

        } catch(IOException e) {
            e.printStackTrace();
        }       
    }   
}

由于我对所有这些多线程的东西都不熟悉,可能还有其他一些错误,如果你能告诉我,我会很高兴的。

【问题讨论】:

  • 你在这段代码中有几个重要的问题,更不用说过度使用静态了,但它看起来是你的嵌套 while 循环正在杀死你。一旦内循环开始,外循环就无关紧要了。您不想要一个循环,即内部循环,它同时检查 BufferedReader 的状态在线状态吗?
  • readline() 也需要中断。查看stackoverflow.com/questions/3595926/…的答案

标签: java multithreading atomic synchronized volatile


【解决方案1】:

嵌套循环有问题:

while(GUI.getOnlineState()) {
    while((input = in.readLine()) != null) {
        out.println(input);
    }
}

一旦进入内部循环,它将继续循环,直到输入流不再工作,您将无法摆脱它。也许更好的是完全摆脱外部循环并结合您的逻辑:

while(GUI.getOnlineState() && (input = in.readLine()) != null) {
    out.println(input);
}

其他不相关的问题是您过度依赖静态字段和方法,这可能适用于小型玩具程序,但随着您的程序变得更大并且可能有更多错误,这可能会增加问题。静态可能会增加不应连接的事物的连接性,增加代码的圈复杂度,从而增加错误的风险。将您的关注点隔离到私有实例字段和所需的最少公共方法中。

【讨论】:

  • 好吧,这很奇怪......我也想知道那个嵌套循环,但它不能与之前的组合逻辑一起工作,所以我做了这两个循环(并没有真正考虑过拼命地试图找到一个解决方案)但现在它正在工作,所以谢谢
猜你喜欢
  • 2019-05-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多