Java access object outside thread

别说谁变了你拦得住时间么 提交于 2020-08-20 12:39:22

问题


I want to access the instance created in t1 from outside the thread, is this possible? So I can close the socket after the thread is executed.

Network class:

public class Network {

    Socket socket;

    public void changeConnection(String command)
    throws Exception { // Whatever exceptions might be thrown
        if (command.equals("connect")) {
            socket = new Socket(server, port);
        }
        else if (command.equals("disconnect")) {
            socket.close();
        }
    }
}

Main class:

public class Project1 {

    public static void main(String[] args) throws Exception {
        Thread t1 = new Thread(new Runnable() {

            @Override
            public void run() {
                try {
                    Network network = new Network();
                    network.connect("connect");
                }
                catch (Exception ex) {

                }
        }
        });
        t1.start();
        Thread.sleep(20000);
        network.connect("disconnect");
    }
}

回答1:


Yes, that's possible.

In your code, the t1 variable is local to main(String[] args):

public static void main(String[] args) {
    Thread t1 = ...
}

You cannot access local variables from outside the method where they are declared. In order to do so, you just need to turn the local variable into a class member (also known as field or class property). Then you can set the access modifier to define which classes can access it.

public class Project1 {

    protected static Thread t1;

    public static void main(String[] args) {
        t1 = new Thread...
    }
}

The t1 inside main() refers to the class member t1. Of course, because your main() method is static, you also need the class member you want to access from within main() to be static. You can set the access modifier of t1.

Another way to do it

But if you want to close the connection after the thread is executed, then why don't you just close it as the last statement of the thread?

public static void main(String[] args) throws Exception {
    Thread t1 = new Thread(new Runnable() {

        @Override
        public void run() {
            try {
                Network network = new Network();
                network.changeConnection("connect");

                // Do loads of work...

                // All work has been done and we're done with the
                // connection. Why don't we close it just now?
                network.changeConnection("disconnect");
            }
            catch (Exception exc) {
                // Catch the exception properly
            }
        }
    });
    t1.start();
}

Or using a lambda expression:

Thread t1 = new Thread(() -> {
    // body of run()
});
t1.start();

PS: You should always start class names (like Project1) with an uppercase character.




回答2:


Why you want to open the socket connection in new thread as a non-static object? Because if you are opening the connection then certainly you want to close the connection.
Now if you are opening it in a new thread and as non-static socket connection object then you have keep your main thread alive who is holding the object/handler of the your socket connection so that in the end you can close it, otherwise socket connection will never be closed and the resources and RAM area it had occupied will never be freed.

Disclaimer: Without understanding your complete requirement it is hard to give you a fitting solution but my speculative solutions for you are as below, choose which fits your case/requirement:

One approach:
Generally, database connections are opened as a static object so that it can be accessed by many threads and later be closed be some/last thread. So, you can create a your SocketConnection class and create a static java.net.Socket object, which will be used by all your threads, and once everything is done over that socket connection then your last thread will close the socket connection.

Another approach (use java.lang.ThreadLocal):
If you want to pass some information/object to other pieces of code without passing it in method parameters then ThreadLocal is your friend. It will help you pass the object to any portion of code which is being executed by same thread. ThreadLocal has thread scope, so now you can understand that anything you will put in ThreadLocal will be valid until that thread is alive.
Read this nice tutorial on how to use ThreadLocal.

Another approach (solely based on the code example you used):
I guess you are using Thread.sleep(20000); so that by this sleep is over your thread t1 would have finished opening socket connection, and then you can do something, and at-last close socket connection.
If that is the case, then using sleep() method like this is not recommended. So, after thread has started, you can check if it has finished execution, and if yes then you can do whatever you wish. Below is code example:

    final Network network = new Network();
    Thread t1 = new Thread(new Runnable() {
        @Override
        public void run() {
            System.out.println("Thread started...");
            try {
                network.changeConnection("connect");
            }
            catch (Exception ex) {

            }
    }
    });
    t1.start();
    System.out.println("Thread start command executed...");
    //Thread.sleep(20000);
    while(t1.isAlive()){
        //Do nothing...
    }
    network.changeConnection("disconnect");



回答3:


As I think your problem, the solution should be like this. Main class:

public class project1 {

    static Thread t1 = null;

    public static void main(String[] args) throws Exception {

        t1 = new Thread(new Runnable() {

            public void run() {
                try {
                    network network = new network();
                    network.connect("connect");
                }
                catch (Exception ex) {

                }
            }
        });
        t1.start();
        Thread.sleep(20000);
        network.connect("disconnect");
    }
}

Now you can access it anywhere in Project1 class.



来源:https://stackoverflow.com/questions/30679841/java-access-object-outside-thread

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!