考虑以下两种run
方法的设计:
接近A
public void run() {
do {
//do something
} while (condition);
}
方法B
public void run() {
//do something...
if (condition) {
new Thread(this).start();
}
}
第二种方法对我来说似乎更清洁,经过一番辩论后,我被告知使用方法二并不是一个好主意。
问题:
答案 0 :(得分:4)
这里有两件事。循环,以及在新线程中连续运行自身直到满足条件(不是循环)的方法。
如果你需要一个循环,你会选择每个人都能理解并完美运作的标准普通循环。
如果你需要编写一个奇怪的代码片段,无缘无故地创建新的线程,并让其他开发人员怀疑你的技能和理解,你会选择B。
你的选择B 绝对没有意义,除非会有一些额外的东西,如队列或ThreadPoolExecutor参与重新调用方法,所以该方法最后会添加this
对于以后的调用,有点像“懒惰的循环”。
答案 1 :(得分:1)
因为方法B比方法A使用多一个线程。由于多种原因,创建线程很昂贵@see Why is creating a Thread said to be expensive?
对于读者,IMO来说,方法A也有点清晰。最简单的选择通常是。答案 2 :(得分:1)
第二个选项在每次迭代时都会创建一个新线程,因此最终会产生不必要的代价,尤其是当选项A执行相同操作但不为每次迭代创建新线程时。
答案 3 :(得分:0)
我能为模式B找到的唯一好的用例是,如果在重新运行该方法之前存在明显的延迟。例如,某种轮询系统应该每隔X分钟运行一次,直到系统关闭为止。
在这种情况下,使用调度程序而不是Thread.sleep(fiveMinutes)
是有意义的,以避免不必要地占用资源(可能你正在坚持数据库连接等)。
请注意,在这种情况下,您使用的是调度程序,而不仅仅是Thread#start
,因此我允许对模式B进行相当自由的解释。
答案 4 :(得分:0)
他们的表现会有很大不同。
第一个解决方案将循环,直到condition
为假,然后终止。
第二个解决方案将启动一个新线程并死掉,直到condition
为假。它可能会完成您想要做的事情但会浪费大量资源来分配和销毁新线程。
这是一个循环超过5个值并打印值和当前线程名称的示例:
<强>循环强>:
Runnable loop = new Runnable() {
int i = 0;
@Override
public void run() {
do {
System.out.printf("%s: %s%n", Thread.currentThread().getName(), i);
i++;
} while(i < 5);
}
};
loop.run();
主要:0
主要:1
主要:2
主要:3
主要:4
<强>螺纹强>:
Runnable thread = new Runnable() {
int i = 0;
@Override
public void run() {
System.out.printf("%s: %s%n", Thread.currentThread().getName(), i);
i++;
if(i < 5) {
new Thread(this).start();
}
}
};
thread.run();
主要:0
线程0:1
线程-1:2
线程-2:3
线程3:4
正如您所看到的,线程示例在不同的线程上打印每一行,这非常浪费,可能不是您想要完成的。