2014-10-04 62 views
0

我想开始说如果你知道更好的方法来做到这一点,请告诉我。我宁愿知道一个更好的做法,而不是做得不对。如何引用Thread类的新实例?

我在写一个服务器程序,它必须与多个客户端交互。我正在使用这个答案提出的方法。 (socket programming multiple client to one server)。我正在创建'EchoThread'的新实例。

我也有另一个类,有一些变量,需要能够被我的服务器中的所有类/操作访问和更改。我想知道如何从创建新的'EchoThread'对象和'EchoThread'类的类中注入(我认为就是它所称的)实例。从上面的链接的答案

部分:

while (true) { 
     try { 
      socket = serverSocket.accept(); 
     } catch (IOException e) { 
      System.out.println("I/O error: " + e); 
     } 
     // new threa for a client 
     new EchoThread(socket).start(); 
    } 

我有类的实例我要注入:

VarsClass vars = new VarsClass(); 

我通常“链接”,这些做的事:

VarsClass vars = new VarsClass(); 
ExampleClass example = new ExampleClass(); 
example.link(vars); 

这是'ExampleClass'中的'link'方法

public void setGlobalVariables(GlobalVariables global) { 

    this.globalVariables = global; 

} 

我如何在'ExmapleClass'和'VarsClass'中引用'EchoThread'?我正在这样做,所以每个类都不创建VarsClass的新实例。 (避免我在这里的问题:Using the same variables in two threads, but I don't know why they won't update in Java

非常感谢您提前给予每一位的耐心和帮助。 〜Rane

+0

你可以在这里注入:'new EchoThread(socket).start();'。给EchoThread的构造函数另一个参数或更多。 – 2014-10-04 00:51:38

+0

不要这样写代码。启动线程的行应该在try块内:否则,如果有异常,您将使用上次接受的套接字启动另一个线程。取决于try块中代码成功的代码也应该放在try块中。 – EJP 2014-10-04 02:17:03

回答

0

您可以像使用任何其他类的实例一样执行此操作。

EchoThread thread = new EchoThread(socket); 
thread.setGlobalVariables(globalVars); 
thread.start(); 
1

如何引用EchoThread ...

简单的方法是这样的:

EchoThread et = new EchoThread(socket); 
et.link(vars); 
et.start(); 

或者通过vars对象作为另一个参数构造函数。


请注意,以下变体是错误的...除非您使EchoThread线程安全。

EchoThread et = new EchoThread(socket); 
et.start(); 
... 
et.link(vars); 

(它是安全的说法之前传递给start()呼叫,因为有一个明确的“之前发生”关于start()电话...调用start()线程和新线程的起点之间run()方法。)


另外要注意的是,Thread中编写子类通常被认为是实现多线程的一个好办法。更好的方法是将您的线程逻辑实现为Runnable;例如

public class MyRunnable implements Runnable { 
    // thread state variables here ... 
    public MyRunnable(Socket sock, GlobalVariables vars) { 
     ... 
    } 

    public void run() { 
     // thread logic goes here ... 
    } 
} 

,并使用它像这样:

new Thread(new MyRunnable(sock, vars)).start(); 

这种方法可以让你轻松改变你的代码,使用一个线程池或遗嘱执行人,而不是你动态创建一个线程。 (在线创建线程往往很昂贵。)