Java/线程的 start 和 run 方法的区别
- 直接调用线程的 run 方法,并不会启动一个新的线程,而是在原来的线程里面执行 run() 方法里面的语句,与普通的方法调用没有差别
- 调用线程的 start 方法,是启动一个新的线程去执行 run() 方法里面的代码 如下示例: 上述代码中,调用线程的 run() 方法,输出是:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21public class ThreadTest {
private static void attack(){
System.out.println("Fight");
// 打印当前线程名字
System.out.println("Current Thread is: "+ Thread.currentThread().getName());
}
public static void main(String[] args) {
Thread t=new Thread(){
@Override
public void run() {
//在子线程里面调用 attack 方法,打印线程名字
attack();
}
};
//打印主线程名字
System.out.println("Current Thread is: "+ Thread.currentThread().getName());
//调用线程的 run() 方法
t.run();
}
}把其中的1
2
3Current Thread is: main
Fight
Current Thread is: maint.run();
改成t.start();
后,输出如下:证明了 start() 方法会开启一个新的线程,而 run() 方法不会开启新线程 我们可以进入到 start 方法的源码中查看:1
2
3Current Thread is: main
Fight
Current Thread is: Thread-0
1 | public synchronized void start() { |
可以看到在 start() 方法里调用了 start0() 方法来启动一个新线程的,而 start0() 方法是一个 native 方法,可以通过下面链接查看 openJDK 对应的代码http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/6f7370a85071/src/share/native/java/lang/Thread.c 1
2
3
4
5
6static JNINativeMethod methods[] = {
{"start0", "()V", (void *)&JVM_StartThread},
...
...
...
};1
2
3
4
5
6
7
8
9
10JVM_ENTRY(void, JVM_StartThread(JNIEnv* env, jobject jthread)){
...
...
...
//创建一个新线程
native_thread = new JavaThread(&thread_entry, sz);
...
...
...
}new JavaThread(&thread_entry, sz)
创建一个新线程的。其中 thread_entry 的定义如下:
1 |
|

# Thread 和 Runnable 是什么关系 - Thread 是实现了 Runnable 接口的类,使得 run 方法支持多线程。我们可以通过重写 Thread 的 run 方法实现多线程,也可以将 Runnable 的对象传递给 Thread 的构造方法实现多线程。 - 由于类的单一继承原则,为了提升代码的可扩展性,推荐多使用 Runnable 接口