线程的创建
概述
1.Thread类创建线程
2.Runnable接口创建线程
3.Callable接口创建线程
4.线程的生命周期
第1节 Thread类创建线程
可以通过继承Thread的方式创建线程。
1. 定义Thread类的子类,并重写该类的run()方法,该run()方法的方法体就代表了线程需要完成的任务。
2. 创建Thread子类实例,即创建了线程对象。
3. 调用线程对象的start()方法来创建并启动线程。
代码语言:javascript复制public class HelloWorldThread extends Thread {
/**
* 重写run()方法,run()方法的方法体就是线程的执行体
*/
@Override
public void run(){
System.out.println("Hello Concurrent World");
}
public static void main(String[] args) {
System.out.println("--------创建线程--------");
HelloWorldThread helloWorldThread = new HelloWorldThread();
System.out.println("--------启动线程--------");
helloWorldThread.start();
}
}
第2节 Runnable接口创建线程
1. 定义Runnable接口的实现类,并重写该接口的run()方法,该run()方法的方法体就是线程的线程执行体。
2. 创建Runnable实现类的实例,并以此实例作为Thread类的target来创建Thread对象,该Thread对象才是真正的线程对象。
代码语言:javascript复制public class HelloWorldRunnable implements Runnable {
@Override
public void run() {
System.out.println("Hello Concurrent World");
}
public static void main(String[] args) {
System.out.println("--------实现Runnable接口--------");
HelloWorldRunnable helloWorldRunnable = new HelloWorldRunnable();
System.out.println("--------创建线程--------");
Thread thread = new Thread(helloWorldRunnable);
System.out.println("--------启动线程--------");
thread.start();
}
}
第3节 Callable接口创建线程
1. 创建Callable接口的实现类,并实现call()方法。该call()方法将作为线程的执行体,且该call()方法有返回值,再创建Callable实现类的实例
2. 使用FutureTask类来包装Callable对象,该FutureTask对象封装了该Callable对象的call()方法的返回值。
3. 使用FutureTask对象作为Thread对象的target创建并启动新线程。
4. 使用FutureTask对象的get()方法来获得子线程执行结束后的返回值。
代码语言:javascript复制public class HelloWorldCallable {
public static void main(String[] args) {
// FutureTask对象
// Lambda表达式
FutureTask task = new FutureTask(() -> {
int count = 0;
for (int i = 0; i <= 100; i ) {
count = i;
}
return count;
});
// 创建线程
Thread thread = new Thread(task);
// 启动线程
thread.start();
try {
// 获取线程返回值
System.out.println("1 2 3 ... 100 = " task.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
【注意】
除了以上几种方式可以创建线程外,还可以通过线程池创建线程。此处暂不对线程池做过多讲解。
第4节 线程的生命周期
线程从生到死经历的生命周期为:
1. 新建
new关键字创建线程对象时的状态
2. 就绪
通过线程对象的start()方法启动线程时对应的状态,此时线程并不一定马上能进入运行状态,线程的运行由操作系统的调度程序控制。
3. 运行
线程获得CPU的执行权,线程正在执行需要执行的代码
4. 阻塞
BLOCKED称为阻塞状态,或者说线程已经被挂起,线程“睡着”了,原因通常是因为线程在等待一个“锁”。
5. 等待
分为有限期等待和无限期等待
6. 线程结束
线程各状态转换如下图所