什么时候用Java thread.run()
代替thread.start()
?
t.run()
要t
在当前线程上运行的任务,以及t.start()
要t
在线程t
本身上运行的任务时。还是您要询问实际用例?
start()
!像我一样...此方法不应公开!
什么时候用Java thread.run()
代替thread.start()
?
t.run()
要t
在当前线程上运行的任务,以及t.start()
要t
在线程t
本身上运行的任务时。还是您要询问实际用例?
start()
!像我一样...此方法不应公开!
Answers:
决不。就像常规方法调用一样,直接调用run()只是在同一线程中同步执行代码。
问:线程的start()和run()方法有什么区别?
答:Thread类中单独的start()和run()方法提供了两种创建线程程序的方法。start()方法开始执行新线程并调用run()方法。start()方法立即返回,并且新线程通常继续运行,直到run()方法返回。
Thread类的run()方法不执行任何操作,因此子类应使用在第二个线程中执行的代码覆盖该方法。如果使用Runnable参数实例化Thread,则该线程的run()方法将在新线程中执行Runnable对象的run()方法。
根据线程程序的性质,直接调用Thread run()方法可以提供与通过start()方法进行调用相同的输出,但是在后一种情况下,代码实际上是在新线程中执行的。
thread's run() method executes the run() method of the Runnable object in the new thread instead.
这是不正确的(或者至少我的Java 8源代码另有说明),但是不幸的是链接似乎断开了,所以我在这里报告了错误。
thread.run()
代替thread.start()
。
这已经暗示过了,但要明确一点:创建一个仅用于调用它的run()方法的新Thread对象不必要地昂贵,并且应该是一个主要的危险信号。创建一个Runnable impl是一个更好,更分离的设计,并且(a)如果这是所需的行为,则直接调用它的 run()方法,或者(b)使用该Runnable构造一个新的Thread并启动Thread。
更好的是,要进行更多的去耦,请查看Executor
JDK 5和更高版本中的接口和框架。这使您,简单地说,解耦任务执行(Runnable的实例)从如何执行它(的Executor实现,这可能会在当前线程从池中执行的Runnable,在一个新的线程,使用现有的线程,等等)。
单独start()
和run()
在Thread类方法提供了两种方法来创建线程程序。该start()
方法开始执行新线程并调用该run()
方法。该start()
方法将立即返回,并且新线程通常会继续运行,直到该run()
方法返回为止。
Thread类的run()
方法不执行任何操作,因此子类应使用在第二个线程中执行的代码覆盖该方法。如果使用Runnable参数实例化了Thread,则该线程的run()
方法将run()
在新线程中执行Runnable对象的方法。
根据线程程序的性质,run()
直接调用Thread 方法可以提供与通过start()
方法调用相同的输出,但是在后一种情况下,代码实际上是在新线程中执行的。
The start() method returns immediately and the new thread normally continues until the run() method returns.
如果start()
立即返回怎么来的run()
继续运行,因为它是从称呼自己start()
如果问题是-“为什么调用线程启动方法而不是直接运行方法”,那么我已经用下面的示例代码回答了。希望能澄清。在下面的示例中:
/*
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");
}
}
如果要像其他任何方法一样执行run()的内容。当然,不启动线程。
假设您知道启动和运行方法的用法,即同步与异步;run方法只能用于测试功能。
加上在某些情况下,可以通过在两个不同的对象中调用一个人的run方法和另一个人的start方法来在具有同步和异步功能要求的两个不同的地方使用同一线程类。
至少在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();
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());
}
}