简体   繁体   中英

Java: Sharing and calling variables between threads

I made a basic server using sockets and wanted to add a simple GUI to turn it on and off. To make the GUI still work while the server is running a while-loop, i created a thread for the sockets. Now what i was thinking of was adding a boolean to that while-loop which exits said loop and causes the server to stop when pressing a button in the GUI.

Now the problem is that the boolean is set in the GUI thread and needs to be called in the server thread. I read about setting the boolean to volatile or using an AtomicBoolean but neither of them seemed to work. Is there maybe something special i need to look for when calling the boolean from the server thread?

This is the (simplified) code i wrote so far:

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;
    }
}

and the class containing the server thread:

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();
        }       
    }   
}

Since i'm new to all this multithreading stuff, there might be some other mistakes which i'd be glad if you would tell me about.

The nested loop is a problem:

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

Once the inner loop is entered, it will continue looping until the input stream is no longer working, and you will have no way of breaking out of it. Perhaps better would be to get rid of the outer loop entirely and combine your logic:

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

Other unrelated issues are your over-reliance on static fields and methods, something that might work for small toy programs but that risks increasing problems as your program gets bigger and potentially more buggy. Statics risk increasing the connectedness of things that shouldn't be connected, increasing the cyclomatic complexity of your code, and thus the risk of bugs. Isolate your concerns into private instance fields and minimal public methods needed.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM