线程外的Java访问对象

时间:2015-06-06 06:46:27

标签: java multithreading sockets object

我想从线程外部访问在t1中创建的实例,这可能吗?所以我可以在执行线程后关闭套接字。

网络课程:

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

主要课程:

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

3 个答案:

答案 0 :(得分:0)

是的,这是可能的。

在您的代码中,t1变量是main(String[] args)的本地变量:

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

您无法从声明它们的方法之外访问本地变量。为此,您只需将局部变量转换为class member(也称为字段类属性)。然后,您可以设置访问修饰符以定义可以访问它的类。

public class Project1 {

    protected static Thread t1;

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

t1内的main()是指班级成员t1。当然,因为您的main()方法是静态的,所以您还需要要在main()内访问的类成员是静态的。您t1可以set the access modifier

另一种方法

但是如果你想在线程执行后关闭连接,那么为什么不把它作为线程的最后一个语句关闭呢?

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

PS:您应该始终使用大写字符启动类名(例如 Project1 )。

答案 1 :(得分:0)

为什么要在新线程中打开套接字连接作为非静态对象?因为如果您打开连接,那么您肯定要关闭连接 现在,如果你在一个新线程和非静态套接字连接对象中打开它,那么你保持你的主线程活着谁持有你的套接字连接的对象/处理程序,以便最后你可以关闭它,否则socket连接永远不会被关闭,它所占用的资源和RAM区域永远不会被释放。

免责声明:如果不了解您的完整要求,很难为您提供合适的解决方案,但我的推测解决方案如下,请根据您的情况/要求选择:

一种方法:
通常,数据库连接作为静态对象打开,以便许多线程可以访问它,之后可以将其关闭为某个/最后一个线程。因此,您可以创建一个SocketConnection类并创建一个静态java.net.Socket对象,该对象将被所有线程使用,一旦通过该套接字连接完成所有操作,则最后一个线程将关闭套接字连接。

另一种方法(使用java.lang.ThreadLocal):
如果你想将一些信息/对象传递给其他代码而不在方法参数中传递,那么ThreadLocal就是你的朋友。它将帮助您将对象传递给由同一线程执行的代码的任何部分。 ThreadLocal有线程范围 ,所以现在您可以理解,在{0}}中放置的任何内容在该线程处于活动状态之前都有效。
阅读how to use ThreadLocal上的这个好教程。

另一种方法(仅基于您使用的代码示例):
 我猜你正在使用ThreadLocal,所以通过这个睡眠结束你的线程Thread.sleep(20000);将完成打开套接字连接,然后你可以做一些事情,并且最后关闭套接字连接。
如果是这种情况,则不建议使用像这样的sleep()方法。因此,在线程启动后,您可以检查它是否已完成执行,如果是,那么您可以执行任何操作。下面是代码示例:

t1

答案 2 :(得分:-1)

我认为你的问题,解决方案应该是这样的。 主要课程:

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

现在,您可以在Project1类中的任何位置访问它。