简介
- 定义:多条执行流程并行的技术
- 优点:异步执行,避免同步等待
创建-继承Thread
代码实现
- 继承Thread类
重写run
方法- 新建自建线程的实例
调用start
方法
- 继承Thread类
- 重写run方法
/*** 1. 继承Thread类* 2. 重写run方法*/
public class MyThread extends Thread{private String name;public MyThread(String name) {this.name = name;}@Overridepublic void run() {try {sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println(this.name + " is running.");}
}
- 新建自建线程的实例
- 调用start方法
MyThread myThread = new MyThread("Thread1");
myThread.start();
System.out.println("不影响主线程的执行");
优缺点
- 优点:最
简单
的实现方式- 缺点:已经继承了Thread类,无法继承其他类,
不利于扩展
创建-实现Runnable接口
- 新建一个
任务类
,实现runnable接口- 重写run方法
- 创建runnable实例对象
把runnable实例对象传递给Thread对象
调用thread的start方法
- 实现runnable接口
- 重写run方法
public class MyRunnable implements Runnable {@Overridepublic void run() {try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println("MyRunnable is running.");}
}
- 创建runnable实例对象
把runnable实例对象传递给Thread对象
调用thread的start方法
MyRunnable myRunnable = new MyRunnable();
Thread thread = new Thread(myRunnable);
thread.start();
System.out.println("不影响主线程的执行");
创建-匿名内部类
如果是只使用一次的任务调度,可以使用匿名内部类
- 使用匿名内部类代替定义一个实现类
- 匿名内部类重写run方法
将runnable任务类实例交给线程类实例
- 调用线程类实例的start方法
// 匿名内部类// 如果只使用一次,可以使用匿名内部类Runnable myRunnable = new Runnable() {@Overridepublic void run() {try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println("MyRunnable is running.");}};// 后续操作是一样的Thread thread = new Thread(myRunnable);thread.start();System.out.println("不影响主线程的执行");
方法体足够简单,是可以使用lambda表达式来实现的
创建-Callable接口
callable接口的出现是为了解决问题的
实现方式
- 定义一个Callable接口的实现类
- 实现类使用泛型,声明返回的结果类型
// 泛型定义的是返回值的类型
public class MyCallable implements Callable<CalResult> {@Overridepublic CalResult call() throws Exception {CalResult calResult = new CalResult(0);for (int i = 0; i < 100; i++) {calResult = new CalResult(calResult.getResult() + i);}return calResult;}
}
定义一个类,来接受子线程的运行结果
public class CalResult {private int result;public CalResult(int result) {this.result = result;}public int getResult() {return result;}
}
1.创建一个Callable对象
2.使用FutureTask来包装Callable对象
3.创建一个线程对象 将FutureTask对象作为参数传递给Thread对象
4.启动线程
5.获取线程执行结果
// 1.创建一个Callable对象
MyCallable myCallable = new MyCallable();
// 2.使用FutureTask来包装Callable对象
// FutureTask是Future的实现类,FutureTask实现了Runnable接口
// FutureTask的泛型参数是Callable对象的返回值类型
FutureTask<CalResult> futureTask = new FutureTask<>(myCallable);
// 3.创建一个线程对象 将FutureTask对象作为参数传递给Thread对象
Thread thread = new Thread(futureTask);
// 4.启动线程
thread.start();
try {// 5.获取线程执行结果// get()方法会阻塞当前线程,直到子线程执行完毕,然后获取子线程的执行结果CalResult calResult = futureTask.get();System.out.println("result: " + calResult.getResult());
} catch (InterruptedException | ExecutionException e) {e.printStackTrace();
}