大多数时候我想在一个新线程中运行一段代码,它会耗费一些时间,但在某些情况下我想用调用方法的线程运行它。直接调用run方法是不好的做法吗?
如果不是一个好主意,最好将代码放在另一个可以被新线程调用或复制代码的方法中吗?
这是一些示例代码,它只是为了说明我想要实现的目标:
class Main {
public Main() {
new Thread(new WorkerThread(1, 2)).start(); // This is what I'd do if I wanted it to run in a new thread.
new WorkerThread(1, 2).run(); // Is it bad practice to do this?
}
}
class WorkerThread implements Runnable {
private int int1, int2;
public WorkerThread(int int1, int int2) {
this.int1 = int1;
this.int2 = int2;
}
public void run() {
// Do something time consuming with the ints.
}
}
答案 0 :(得分:4)
调用run同步执行代码;而run方法将允许代码异步执行。
在需要避免线程的测试场景中,直接调用run通常是有益的。
答案 1 :(得分:3)
您可以直接调用run方法,但这将在您当前的线程中执行。不会创建额外的线程。然而,调用“start”将创建一个新线程并在内部调用run方法。
因此,如果您正在寻找线程创建,则需要使用start方法。
更多详情here
答案 2 :(得分:2)
在现在过时的Java Blackberry API中,Runnable
的实现用于各种事物,例如definition of GUI callbacks。接口Runnable
可以看作是面向对象的定义函数指针的方式,因此Runnable
和多线程首先是正交概念。
答案 3 :(得分:2)
一个好主意是使用Extract Method(重构技术)来提取需要直接运行的run方法的部分(可能是全部)。
class Worker implements Runnable {
private int int1, int2;
public Worker(int int1, int int2) {
this.int1 = int1;
this.int2 = int2;
}
public void work() {
...
}
public void run() {
work();
}
}
然后
new Thread(new WorkerThread(1, 2)).start();
new WorkerThread(1, 2).work(); // Looks good!
答案 4 :(得分:2)
我知道已经有很多其他答案,但你的问题是关于"练习",而且这个词没有出现在其中任何一个。
什么是良好的做法是编写易于其他人理解的代码,并且最好在没有任何内联评论的情况下易于理解。
只要" run"的含义,调用foobar.run()
就没有错。对于阅读你的课程的人来说,这是显而易见的。
您的班级名为WorkerThread
,即使不是一个帖子。这可能会让人感到困惑。并且调用workerThread.run()
可能会更加混淆他们是否涉及线程。
我想说,如果有意义的话,继续调用run()
方法,但是改变类,以便读者知道你没有尝试启动一个线程并以错误的方式执行它。
答案 5 :(得分:1)
直接调用run()
的{{1}}方法没有任何问题。
在Java 1.4和1.5的早期版本中(不可否认是由于某个错误),如果您创建Runnable
但不继续调用其Thread
方法可能会出现问题,因为资源是分配的,永远不会释放。
请参阅Why is my Java program leaking memory when I call run() on a Thread object?
您的代码可以避免这种情况 - 您拨打start()
的对象不是run()
。如果你这样做了:
Thread
...然后在有缺陷的JVM中,分配给 class WorkerThread extends Thread {
public void run() { ... }
}
...
public void main() {
WorkerThread a = new WorkerThread();
WorkerThread b = new WorkerThread();
a.start // runs parallel to main thread
b.run(); // runs in main thread
}
的资源不会被清除。
您应该让JVM错误(在您可能没有定位的版本上)影响您的编码风格并不明显。但是,很明显,代码错误地表明了它的意图。我们不打算在单独的线程中运行此代码,因此我们不应将其声明为线程。 b
样式(已使用)的引入使得只有创建new Thread(Runnable x)
才能轻松创建Threads
。
我对您的代码的唯一建议是更改WorkerThread
的名称 - 因为它并不总是一个帖子。 Worker
将是一个很好的通用名称。在实际代码中,你会给它一个名称,表明它的工作类型!
new Thread(new Worker(1, 2)).start();
new Worker(1, 2).run();
正如已经注意到的那样 - 除了包装在一个线程中之外,还有Runnable
的用法。这两个概念没有紧密结合。