Melon Playground甜瓜游乐场
98.73M · 2026-03-22
创建一个线程的方法,有非常多种:
继承Thread类,重写run方法。
实现Runnable接口,实现run方法,然后将Runnable实例传递给Thread构造器。
实现Callable接口,结合FutureTask和Thread类(这是对Runnable的功能增强,用于获取返回值)。
创建一个子类继承Thread类,并且重新run方法
Thread thread=new Thread(){
@Override
public void run() {
while(true){
System.out.println("线程执行中...");
}
}
};
通过实现Runnable接口,重写run方法
Runnable runnable=new Runnable() {
@Override
public void run() {
while(true){
System.out.println("线程执行中...");
}
}
};
Thread thread=new Thread(runnable);
Callable<String> callable=new Callable<>() {
@Override
public String call() throws Exception {
Thread.sleep(2000);
return "hello,JUC";
}
};
FutureTask<String> task=new FutureTask<String>(callable);
Thread thread=new Thread(task);
thread.start();
String s = task.get();
System.out.println(s);
现在来看看Thread的背后做了什么事。
public class Thread implements Runnable {
private Runnable target;
@Override
public void run() {
if (target != null) {
target.run();
}
}
}
从上述简化的代码来看,Thread本质也是一个Runnable,并且还持有一个Runnable对象。
因此上面的几种方法都有了解释:
Thread,直接覆写run方法的逻辑,不再使用target。target,执行target中的run方法以下是start的源码
public synchronized void start() {
if (threadStatus != 0)
throw new IllegalThreadStateException();
group.add(this);
boolean started = false;
try {
start0();
started = true;
} finally {
try {
if (!started) {
group.threadStartFailed(this);
}
} catch (Throwable ignore) {
}b
}
}
start方法被synchronized修饰,确保在多线程环境下,检查线程状态和启动过程是原子的,防止一个线程对象被并发启动多次。
threadStatus为0时,代表着是NEW状态,此时线程对象创建了,但是没有启动,如果threadStatus不为0,说明线程已经启动了。
通过启动加锁与检查线程状态,保证了线程不可重复启动的特性。
从代码中并没有看到run方法被调用的语句,因为真正的启动在start0中