目录
(3)线程的创建方式三:利用Callable接口,FutureTask类来实现
1.线程的创建
(1)线程的创建方式一:继承Thread类
/*
* 1.定义一个任务类,实现Runnable接口
*/
public class MyThread extends Thread{
// 重写runnable的run方法
@Override
public void run() {
for (int i = 0; i <=10 ; i++) {
System.out.println("MyThread线程输出"+i);
}
}
}
public class ThreadTest1 {
// main方法是由一条默认的主线程负责执行
public static void main(String[] args) {
// 3.创建MyThread线程类的对象代表一个线程
Thread t=new MyThread();
// 4.启动线程(自动执行run方法的)
t.start();// main线程 t线程
for (int i = 0; i <=10 ; i++) {
System.out.println("主线程main输出"+i);
}
}
}
(2)线程的创建方式二:实现Runnable接口
1.定义一个多线程任务类MyRunnable实现Runnable接口,重写run()方法
2.创建一个Runnable任务对象
3.把MyRunnable任务对象交给Thread处理
public class MyRunnable implements Runnable{
@Override
public void run() {
for (int i = 0; i <=5 ; i++) {
System.out.println("子线程输出"+i);
}
}
}
public class ThreadTest2 {
public static void main(String[] args) {
// 3.创建任务对象
Runnable target=new MyRunnable();
// 4.把任务对象交给一个线程对象处理
new Thread(target).start();
for (int i = 0; i <=10 ; i++) {
System.out.println("主线程main输出"+i);
}
}
}
(3)线程的创建方式三:利用Callable接口,FutureTask类来实现
1.创建任务对象 定义一个类实现Callable接口,重写call方法,封装要做的事情,和要返回的数据 把Callable类型的对象封装成FutureTask(线程任务对象)
2.把线程任务对象交给Thread对象
3.调用Thread对象的start方法启动线程
4.线程执行完毕后,通过FutureTask对象的get方法去获取线程任务执行的结果
import java.util.concurrent.Callable;
public class MyCallable implements Callable<String> {
private int n;
public MyCallable(int n) {
this.n = n;
}
@Override
public String call() throws Exception {
// 描述线程的任务
// 需求: 求1-n的和
int sum=0;
for (int i = 1; i <=n ; i++) {
sum+=i;
}
return "线程求出了1-"+n+"的和是"+sum;
}
}
public class ThreadTest3 {
public static void main(String[] args) throws ExecutionException, InterruptedException {
// 3.创建一个Callable的对象
Callable <String> call=new MyCallable(100);
// 4.把Callable的对象封装成一个FutureTask对象(任务对象)
// 未来任务对象的作用?
// 1.是一个任务对象,实现了Runnable对象
// 2.可以在线程执行完毕后,用未来任务对象调用get方法获取线程执行完毕后的结果
FutureTask <String> f1=new FutureTask<>(call);
// 5. 把任务对象交给一个Thread对象
new Thread(f1).start();
// 6.获取线程执行完毕后返回的结果
String rs= f1.get();
System.out.println(rs);
}
}
2.三种创建线程的优缺点:
1.继承Thread类
优点:代码简洁
缺点:由于是单继承,已经继承了Thread类,就无法继承其他类,拓展性差,功能不足;重写的run方法不能直接返回结果
2.实现Runnable接口
优点:可以实现其它接口,和继承父类,拓展性强
缺点:重写的run方法不能直接返回结果
3.利用Callable接口,FutureTask类来实现
优点:可以返回结果,拓展性强
缺点:代码较繁琐