1:线程创建方式二
让子类继承Thead类
必须重写Thead类的run方法
写多态的写法
注意优缺点 线程已经Thread 无法继承其他类
package threadTest;public class ThreadTest1 {//目标:掌握线程的创建方式继承thread类public static void main(String[] args) {//3:创建MyThead线程类的对象代表一个线程//写多态的写法Thread t=new MyThead();//启动线程(自动执行run方法)t.start(); //main线程 t 线程//t.run(); 会出现bugfor (int i = 1; i <= 5; i++) {System.out.println("主线程main输出"+i);}}
}
public class MyThead extends Thread {//1:让子类继承Thead继承//2:必须重写Thead类的run方法@Overridepublic void run() {for (int i = 1; i <= 5; i++) {System.out.println("子类线程MyThead输出:"+i);}}
}
2:线程创建方式二
优点:任务类只是实现接口,
可以继续继承其他类、实现其他接口,扩展性强
实现类Runnable接口
重写run方法
注意 线程对象和任务对象 不一样
把任务对象交给一个线程对象处理
//1:定义一个任务 实现Runnable 接口
public class MyRunnable implements Runnable {//2:重写Runnable的run方法@Overridepublic void run() {for (int i = 0; i < 5; i++) {System.out.println("Runnable子线程输出:=" + i);}}}
// 掌握多线程的创建方式二 实现类Runnable接口
public class ThreadTest2 {public static void main(String[] args) {//3:创建任务对象Runnable target= new MyRunnable();//4:把任务对象交给一个线程对象处理// 构造器 public Thread(Runnable target)new Thread(target).start();// t.start();for (int i = 0; i < 5; i++) {System.out.println("主程main输出:=" + i);}}
}
2_2:线程创建方式二
匿名内部类写法
Lambda表达式 代码简化
package threadTest;// 掌握多线程的创建方式二 (ni)匿名内部类写法
public class ThreadTest2_2 {public static void main(String[] args) {//1:创建Runnable 接口的匿名内部类形式(任务对象)Runnable target =new Runnable() {@Overridepublic void run() {for (int i = 1; i <=5 ; i++) {System.out.println("子线程1匿名内部类:" + i);}}};new Thread(target).start();//简化形式1;new Thread(new Runnable() {@Overridepublic void run() {for (int i = 1; i <= 5; i++) {System.out.println("子线2程匿名内部类:" + i);}}} ).start();//简化形式2;new Thread(()-> {for (int i = 1; i <= 5; i++) {System.out.println("子线3程匿名内部类:" + i);}} ).start();for (int i = 1; i <=5 ; i++) {System.out.println("主线程main输出:" + i);}}
}
注意 前两种线程创建方式都存在的一个问题
假如线程执行完毕后有一些数据需要返回,他们重写的run方法均不能直接返回结果
解决方法
DK 5.0提供了Callable接口和FutureTask类来实现(多线程的第三种创建方式)
这种方式最大的优点 :可以返回线程执行完毕以后的结果
3线程创建方式三
- 多线程的第三种创建方式:利用 Callab 接口 FuturTask 类库来实现
- 创建 任务
- 定义一个类实现Callable接口 重写call方法
- 封装要做的事情 和要返回的数据
- 把Callable 类型的对象封装成FutureTask(线程任务对象)
- 把线程任务交给Thread对象
- 调用Thread对象的start方法启动线程
- 线程执行完毕后 通过FutureTask对象的get 方法 去获取线程任务执行的结果