线程的创建方式?
线程的创建方式有四种。
- 一、继承 Thread 类创建线程类;
- 二、通过 Runnable 接口创建线程;
- 三、使用匿名内部类的方式;
- 四、通过 Callable 接口和 FutureTask 类来创建线程。
Thread 类
- 定义
Thread 类
的子类,并重写该类的run()
方法,该 run() 方法的方法体就是该线程需要完成的任务。因此把 run() 方法称为执行体。 - 创建 Thread 子类的实例,就是创建了线程对象。
- 调用线程对象的
start()
方法来启动线程。
/**
* @Author : PengPeng
* 第一种创建线程的方式 继承 Thread 类
*/
public class ThreadDemo01 {
public static void main(String[] args) {
System.out.println("====程序开始====");
ThreadDemo001 t1 = new ThreadDemo001();
// start() 方法启动线程
t1.start();
System.out.println("主线程开始");
for (int i = 0; i < 10; i ++){
System.out.println(Thread.currentThread().getName() + ":" + i);
}
System.out.println("主线程结束");
}
}
class ThreadDemo001 extends Thread{
/**
* run 方法里面写需要执行的代码
*/
@Override
public void run() {
System.out.println("子线程开始");
for(int i = 0; i < 10; i ++){
System.out.println(Thread.currentThread().getName() + ":" + i);
}
System.out.println("子线程结束");
}
}
- 执行结果
====程序开始====
主线程开始
main:0
main:1
main:2
main:3
子线程开始
main:4
main:5
main:6
Thread-0:0
main:7
main:8
main:9
主线程结束
Thread-0:1
Thread-0:2
Thread-0:3
Thread-0:4
Thread-0:5
Thread-0:6
Thread-0:7
Thread-0:8
Thread-0:9
子线程结束
Process finished with exit code 0
Runnable 接口
- 定义 Runnable 接口的实现类,并重写该接口的
run()
方法,该 run() 方法的方法体同样是该线程的线程执行体。 - 创建 Runnable 实现类的实例,并以此实例作为 Thread 类的构造函数的参数来创建 Thread 对象,该 Thread 对象才是真正的线程对象。
- 调用该线程对象的 start() 方法来启动该线程。
/**
* @Author : PengPeng
* 第二种创建线程的方式 实现 Runnable 接口,再放入 Thread
*/
public class ThreadDemo02 {
public static void main(String[] args) {
System.out.println("====程序开始====");
ThreadDemo002 t2 = new ThreadDemo002();
Thread thread = new Thread(t2);
thread.start();
System.out.println("主线程开始");
for (int i = 0; i < 10; i ++){
System.out.println(Thread.currentThread().getName() + " : " + i);
}
System.out.println("主线程结束");
}
}
class ThreadDemo002 implements Runnable{
@Override
public void run() {
System.out.println("子线程开始");
for (int i = 0; i < 10; i ++){
System.out.println(Thread.currentThread().getName() + " : " + i);
}
System.out.println("子线程结束");
}
}
- 执行结果
====程序开始====
主线程开始
main : 0
main : 1
子线程开始
main : 2
main : 3
main : 4
main : 5
main : 6
main : 7
Thread-0 : 0
main : 8
Thread-0 : 1
main : 9
主线程结束
Thread-0 : 2
Thread-0 : 3
Thread-0 : 4
Thread-0 : 5
Thread-0 : 6
Thread-0 : 7
Thread-0 : 8
Thread-0 : 9
子线程结束
Process finished with exit code 0
匿名内部类
/**
* @Author : PengPeng
* 第三种创建线程的方式 匿名内部类
*/
public class ThreadDemo03 {
public static void main(String[] args) {
System.out.println("====程序开始====");
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("子线程开始");
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName() + ": " + i);
}
System.out.println("子线程结束");
}
}).start();
System.out.println("主线程开始");
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName() + ": " + i);
}
System.out.println("主线程结束");
}
}
- 执行结果
====程序开始====
主线程开始
main: 0
main: 1
main: 2
main: 3
main: 4
main: 5
子线程开始
main: 6
Thread-0: 0
Thread-0: 1
Thread-0: 2
Thread-0: 3
main: 7
main: 8
main: 9
主线程结束
Thread-0: 4
Thread-0: 5
Thread-0: 6
Thread-0: 7
Thread-0: 8
Thread-0: 9
子线程结束
Process finished with exit code 0
Callable 接口和 FutureTask 类
- 创建 Callable 接口的实现类,并实现
call()
方法,该 call() 方法将作为线程执行体,并且有返回值。 - 创建 Callable 实现类的实例,并以此实例作为 FutureTask 类的构造函数的参数来创建 FutureTask 对象,该封装了该 Callable 对象的 call() 方法的返回值。
- 使用 FutureTask 对象作为 Thread 类的构造函数的参数来创建 Thread 线程对象,并调用 start() 方法来启动该线程。
- 调用 FutureTask 对象的 get() 方法来获得子线程执行结束后的返回值。
/**
* @Author : PengPeng
* 第四种创建线程的方式 Callable 接口和 FutureTask 类
*/
public class ThreadDemo04 {
public static void main(String[] args) throws ExecutionException, InterruptedException {
System.out.println("====程序开始====");
ThreadDemo004 t4 = new ThreadDemo004();
FutureTask futureTask = new FutureTask(t4);
Thread thread = new Thread(futureTask);
thread.start();
System.out.println("主线程开始");
for (int i = 0; i < 10; i ++){
System.out.println(Thread.currentThread().getName() + " :" + i);
}
System.out.println("主线程结束");
// 执行完再拿返回值,不然卡死;
System.out.println("子线程计算出的值为:" + futureTask.get());
}
}
class ThreadDemo004 implements Callable {
@Override
public Object call() throws Exception {
System.out.println("子线程开始");
int temp = 0;
for (int i = 1; i <= 10; i++) {
System.out.println(Thread.currentThread().getName() + " : " + i);
temp += i;
}
System.out.println("子线程结束");
return temp;
}
}
- 执行结果
====程序开始====
主线程开始
main :0
main :1
main :2
子线程开始
main :3
Thread-0 : 1
main :4
main :5
Thread-0 : 2
main :6
main :7
main :8
main :9
主线程结束
Thread-0 : 3
Thread-0 : 4
Thread-0 : 5
Thread-0 : 6
Thread-0 : 7
Thread-0 : 8
Thread-0 : 9
Thread-0 : 10
子线程结束
子线程计算出的值为:55
Process finished with exit code 0
常用 API
常用线程 API 方法 | 常用线程构造函数 |
---|---|
start() 启动线程 | Thread() 分配一个新的 Thread 对象 |
currentThread() 获取当前线程对象 | Thread(String name) 分配一个新的 Thread对象,具有指定的 name 正如其名 |
getID() 获取当前线程 ID | Thread(Runnable r) 分配一个新的 Thread 对象 |
getName() 获取当前线程名称 | Thread(Runnable r, String name) 分配一个新的 Thread 对象 |
sleep() 休眠线程 | |
stop() 停止线程 |
总结:
- 使用继承 Thread 类的方法好,还是使用实现 Runnable 接口的方法好?
使用实现 Runnable 接口的方法好!
因为实现了接口还可以继续继承,继承了 Thread 类就不能在继承其它类了。
- 启动线程是调用 start() 方法还是 run() 方法?
启动线程的方法是
start() 方法