您何时会拨打Java thread.run()
而不是thread.start()
?
答案 0 :(得分:110)
您可能希望在特定的单元测试中调用run(),该测试严格关注功能而不是并发。
答案 1 :(得分:94)
从不。直接调用run()只是同步执行代码(在同一个线程中),就像普通的方法调用一样。
答案 2 :(得分:27)
采取Code Style Java threads FAQ:
问:a之间有什么区别 thread的start()和run()方法?
答:Thread类中提供了单独的start()和run()方法 两种创建线程程序的方法。 start()方法启动 执行新线程和调用 run()方法。 start()方法 立即返回和新线程 通常一直持续到运行() 方法返回。
Thread类的run()方法什么都不做,所以子类应该 用代码覆盖方法 在第二个线程中执行。如果一个 线程用Runnable实例化 参数,线程的run()方法 执行的run()方法 新线程中的Runnable对象 代替。
根据线程程序的性质,调用Thread run()方法直接可以给出 与通过start()调用相同的输出 方法,但在后一种情况下 代码实际上是以新的方式执行的 线程。
答案 3 :(得分:23)
执行thread.run()
不会创建代码执行的新Thread
。它只是执行调用thread.run()
代码的当前Thread中的代码。
执行thread.start()
创建一个新的操作系统级别线程,其中run()
方法被调用。
本质上:
单线程编程→直接调用
run()
方法
多线程编程→调用
start()
方法
此外,正如其他人所说,“测试”似乎是唯一可以直接从您的代码中调用run()
的情况。
答案 4 :(得分:13)
这已经被提到了,但只是要明确:创建一个新的Thread对象只是为了调用它的run()方法是不必要的昂贵,应该是一个主要的红旗。如果这是所需的行为,或者(b)直接调用它的 run()方法,或者(b)用它构造一个新的Thread,那将是一个更好,更分离的设计来创建Runnable impl。 Runnable并启动Thread。
更好的是,为了进一步解耦,请查看JDK 5及更新版本中的Executor
接口和框架。简而言之,这允许您将任务执行(Runnable实例)从如何执行(Executor实现,它可能在新线程中执行当前线程中的Runnable,使用,来自池的现有线程,以及诸如此类的东西。
答案 5 :(得分:9)
致电thread.start()
,然后拨打thread.run()
。如果您想绕过thread.start()
并直接转到thread.run()
答案 6 :(得分:9)
Thread类中的单独start()
和run()
方法提供了两种创建线程程序的方法。 start()
方法开始执行新线程并调用run()
方法。 start()
方法立即返回,新线程通常会继续,直到run()
方法返回。
Thread类'run()
方法什么都不做,所以子类应该覆盖方法,并在第二个线程中执行代码。如果使用Runnable参数实例化Thread,则线程的run()
方法会在新线程中执行Runnable对象的run()
方法。
根据线程程序的性质,直接调用Thread run()
方法可以提供与通过start()
方法调用相同的输出,但在后一种情况下,代码实际上是在新线程。
答案 7 :(得分:7)
如果问题是 - “为什么直接调用线程启动方法而不是直接运行方法”,那么我已经回答了下面的示例代码。希望澄清一下。 在下面的示例中:
/*
By calling t1.start(),
we are getting the main calling thread returned immediately
after the t1.start() called and is ready to proceed for other
operations.And the thread t1 starts executing the run method of the object r.
Hence the the output will be:
I am the main thread , i created thread t1 and had it execute run method, which is currently looping from 0 to 1000000
I am done executing run method of testThread
*/
/* If we call t1.run() instead of t1.start(), (just replace t1.start() with t1.run() in the code for testing)
its like a regular method call and the main thread will not return until the run method completes,
hence the output will be:
I am done executing run method of testThread
I am the main thread , i created thread t1 and had it execute run method, which is currently looping for i to 1000000
*/
class testThread implements Runnable{
public void run()
{
for(int i=0;i<1000000;i++){} //a simple delay block to clarify.
System.out.println("I am done executing run method of testThread");
}
}
public class mainClass{
public static void main(String [] args)
{
testThread r = new testThread();
Thread t1 = new Thread(r);
t1.start(); /* Question is: can we call instead t1.run() */
System.out.println("I am the main thread , i created thread t1 and had it execute run method, which is currently looping for i to 1000000");
}
}
答案 8 :(得分:5)
当您希望它同步运行时。调用run方法实际上不会给你多线程。 start方法创建一个调用run方法的新线程。
答案 9 :(得分:3)
如果要执行run()的内容,就像执行任何其他方法一样。当然不要开始一个帖子。
答案 10 :(得分:3)
假设您知道启动和运行方法的使用,即同步与异步; run方法只能用于测试功能。
另外在某些情况下,同一个线程类可以在具有同步和异步功能要求的两个不同位置使用,方法是使用一个run方法和另一个start方法调用两个不同的对象。
答案 11 :(得分:2)
至少在JVM 1.6。中,有一些检查和运行被称为本机:
public synchronized void start() {
/**
* This method is not invoked for the main method thread or "system"
* group threads created/set up by the VM. Any new functionality added
* to this method in the future may have to also be added to the VM.
*
* A zero status value corresponds to state "NEW".
*/
if (threadStatus != 0)
throw new IllegalThreadStateException();
group.add(this);
start0();
if (stopBeforeStart) {
stop0(throwableFromStop);
}
}
private native void start0();
答案 12 :(得分:2)
只需注意以上很棒的评论:有时你会编写一个多线程代码,它使用“start”方法来运行不同的线程。如果使用“run”(而不是“start”)进行调试,你会发现它更容易,因为它使代码同步运行并更容易调试。
答案 13 :(得分:-1)
public class TestClass implements Runnable {
public static void main(String[] args) {
TestClass tc = new TestClass();
Thread t1 = new Thread(tc);
System.out.println("Before Starting Thread " + Thread.currentThread().hashCode());
t1.start();
System.out.println("After Starting Thread " + Thread.currentThread().hashCode());
}
@Override
public void run() {
System.out.println("TestClass Run method is Running with thread " + Thread.currentThread().hashCode());
}
}