【发布时间】:2016-05-23 07:28:37
【问题描述】:
我发现Thread 对象通常可以以这种方式创建和跟踪:
ArrayList<MyThreadClass> threads = new ArrayList<>();
MyThreadClass myThread = new Thread();
myThread.start();
threads.add(myThread);
但是,与其显式地做所有的事情,不如将它添加到构造函数中并使其发生隐式?
我正在创建一个通用的服务器/客户端程序对,以在我未来的网络应用程序中实现,并且我采用了一些我认为实用的捷径。
我创建了一个“连接”类来跟踪连接到服务器的客户端。它看起来像这样:
class Connection{
private static ArrayList<Connection> clients = new ArrayList<>();
MyListener listener; //extends Thread
Connection(Socket s){
listener = new MyListener(s)
listener.start();
clients.add(this);
}
}
这个类有一个静态 ArrayList 来跟踪所有的连接,构造函数隐式地将每个 new Connection 添加到这个列表中,并启动我的侦听器 Thread 来接收传入的网络流量。
我还有一个ConnectionListener,服务器使用它来接受传入连接并为每个连接创建Connection 实例,如下所示:
while(true){
//try/catch blocks excluded here for the sake of simplicity
new Connection(serverSocket.accept());
}
也许我只是没有偶然发现正确的代码示例,但我很少(如果有的话)看到这种使用构造函数来创建对象并存储它们的引用的方式。我想知道使用列出的任何一种情况是否非常规和/或不切实际,以及它们是否会导致错误。
这样做是否非常规/不切实际:
- 使用
new MyClass()而不存储返回的引用? - 在 List 的构造函数中使用
this关键字将实例添加到 List 中? - 从它的(子)构造函数中启动一个
Thread? - 在构造函数完成之前引用实例会导致问题吗? (在这种情况下,在构造函数本身内)
【问题讨论】:
-
对于codereviews,请转到codereview.stackexchange.com。我的快速cmets:很多坏主意。 static 可能非常dangerous,因为它会使您的代码的测试 变得非常困难。然后:构造函数应该只构造对象......您可能希望将其与启动线程等“实际操作”分离。长话短说:例如,您想阅读有关 en.wikipedia.org/wiki/SOLID_(object-oriented_design) 的信息。然后你想练习 TDD 以提出一个实际上是可单元测试的设计......
-
我投票结束这个问题,因为它属于 codereview.stackexchange.com
-
@Jägermeister 关于codereview:我不是要求人们分析我的代码,我对特定的编程约定有非常具体的问题,这不是文章有资格留在这里吗?
-
这确实不属于代码审查。这里有一些自以为是的元素,但听起来你是still at the whiteboard。
-
@Chexxor 取决于您如何处理连接等。您可以保留套接字列表或
SocketChannel对象;您可以从不同的线程关闭连接,这将导致线程中的异常被阻止从套接字读取数据。您可以捕获异常并从线程的run()方法返回以结束线程。
标签: java multithreading oop constructor static