创建线程的3种方式
1、通过继承Thread重写run方法
重写了Thread类中的run方法,线程执行重写后的run方法
2、通过实现 Runnable 接口中的 run 方法实现创建线程
1、在创建线程时,传入 runnbale 对象,通过一系列传递,最终赋值给Thread类的成员属性 target
2、target 最终在成员方法中判断不为空,则调用target中的run方法,即我们在实现Runnbale 接口中的run方法)
3、通过实现 FutureTask 创建线程
1、FutureTask 实现 RunnableFuture 接口
2、RunnableFuture 继承 Runnable, Future 两个接口,所以间接实现了run 方法
终究到底,都是是重写了Thread中run方法
1、通过继承Thread重写run方法
/**
* @author Deyou Kong
* @description 通过继承Thread重写run方法,底层是Thread在检查是否存在自己的run方法
*
* 1、不可以抛出异常
*
* @date 2023/2/20 12:15 下午
*/
public class ExtendThread extends Thread{
public ExtendThread(String name){
super(name); // 调用父类的带String参数的构造方法
}
@Override
public void run() {
for (int i = 0; i < 5; i++) {
try {
Thread.sleep(10); // 线程登录10ms
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(this.getName() + "线程-" + i);
}
}
}
测试
/**
* @author Deyou Kong
* @description 测试ExtendThread类
* @date 2023/2/20 12:21 下午
*/
public class ExtendThreadTest {
@Test
public void Test01() throws InterruptedException {
System.out.println(Thread.currentThread().getName() + "--测试类主线程开始---1");
ExtendThread extendThread = new ExtendThread("Test01"); // 设置线程名称为Test01
extendThread.start();
System.out.println(Thread.currentThread().getName() + "--测试类主线程---2");
extendThread.join(); // 主线程阻塞在此等待extendThread执行完毕后在执行后续代码
System.out.println(Thread.currentThread().getName() + "--测试类主线程结束---3");
}
}
查看源码:
Thread类中的run方法
我们继承 Thread 类,重写了 run 方法,所以在线程执行的时候,就是跑我们自定义的 run 方法
2、通过实现 Runnable 接口中的 run 方法实现创建线程
public class RunnableThread implements Runnable{
@SneakyThrows
@Override
public void run() {
for (int i = 0; i < 5; i++) {
Thread.sleep(10L);
System.out.println(Thread.currentThread().getName() + "--线程---" + i);
}
}
}
测试类
public class RunnableThreadTest {
@Test
public void Test01() throws InterruptedException {
RunnableThread runnableThread = new RunnableThread();
Thread thread = new Thread(runnableThread, "runnable1");
Thread thread2 = new Thread(runnableThread, "runnable2");
thread.start();
thread2.start();
thread.join();
thread2.join();
System.out.println(Thread.currentThread().getName()+"123");
}
}
- 查看源码:
1、在创建线程时,传入 runnbale 对象,通过一系列传递,最终赋值给Thread类的成员属性 target
2、target 最终在成员方法中判断不为空,则调用target中的run方法,即我们在实现Runnbale 接口中的run方法
3、通过实现 FutureTask 创建线程
public class FutureTaskTaskTest {
@Test
public void Test01() throws InterruptedException, ExecutionException {
FutureTask<Boolean> task = new FutureTask<>(new Callable<Boolean>() {
@Override
public Boolean call() throws Exception {
Thread.sleep(10);
System.out.println("Thread-" + Thread.currentThread().getName() + " is running");
return true;
}
});
Thread thread = new Thread(task, "futureTask");
thread.start();
Boolean aBoolean = task.get(); // 通过 FutureTask 对象的get方法获取返回值,会阻塞直到结果返回
System.out.println(aBoolean);
System.out.println("Thread-" + Thread.currentThread().getName() + " is running");
}
}
查看源码:
1、FutureTask 实现 RunnableFuture 接口
2、RunnableFuture 继承 Runnable, Future 两个接口,所以间接实现了run 方法