我只是想知道在创建自己的自定义对象和扩展Thread以及使用Thread(Runnable)构造函数创建线程之间是否存在一些细微差别?
当我使用扩展Thread的类时,我有一些代码可以正常工作,但是如果我尝试使用通过使用Thread(Runnable)构造函数创建Threads的逻辑,则新线程似乎无法正常工作 - 我不能检测它们的存活方式与我使用自制的自定义子类时的方式相同,并且它们似乎永远不会结束。
在我的代码中,我只是生成一些线程,然后搜索我的线程列表,找到一个活着的并加入它直到它死掉。然后我再一次在列表中搜索一个活着并加入它的线程..这一直持续到所有线程都死掉。
感谢阅读。
答案 0 :(得分:2)
线程是用于工作的资源。 Runnable是一项工作。您是在创建新类型的资源,还是仅仅定义要完成的工作?
要“结束”您只是从“运行”方法返回的线程。需要查看代码的示例,以了解您无法判断它们是否处于活动状态的含义。
创建Runnables当然也可以让您更容易重构代码以便将来使用ThreadPool。
答案 1 :(得分:2)
在我的代码中,我只是生成一些线程,然后在我的线程列表中搜索,找到一个活着的并加入它直到它死掉。
你是如何(以及为什么)“搜索我的线程列表”?我会将Thread
添加到某种Collection
,然后您可以迭代并依次加入每个Thread
:
List<Thread> threads = new ArrayList<Thread();
for (int i = 0; i < 100; i++) {
Thread thread = new Thread(new Runnable() ...);
thread.start();
threads.add(thread);
}
...
for (Thread thread : threads) {
thread.join();
}
更好的方法是使用ExecutorService
给出的Executors
之一。它们在创建线程池和等待池完全完成方面有很多功能。几乎总是推荐new Thread(...)
。
我无法检测到它们的生存方式与我使用自制的子类时相同
如果您要设置Thread
的名称,则无法在Runnable
的构造函数中执行此操作。但可以在run()
方法中执行此操作。你可以这样做:
new Thread(new Runnable() {
public void run() {
Thread.currentThread().setName("...");
}
});
否则,我不确定为什么你不会看到你的Thread
,除非它已经完成。
他们似乎永远不会结束。
使用Runnable
,线程在run()
方法返回时完成 - 通过return
或throw
。这与扩展Thread
非常相似,因此我不确定为什么这不起作用。
答案 2 :(得分:1)
我真的建议使用concurrency utility而不是试图管理自己的线程,这很复杂且容易出错。 使用并发api还可以帮助您立即应用正确的模式。