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(); 会出现bug
for (int i = 1; i <= 5; i++) {
System.out.println("主线程main输出"+i);
}
}
}
public class MyThead extends Thread {
//1:让子类继承Thead继承
//2:必须重写Thead类的run方法
@Override
public 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方法
@Override
public 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() {
@Override
public void run() {
for (int i = 1; i <=5 ; i++) {
System.out.println("子线程1匿名内部类:" + i);
}
}
};
new Thread(target).start();
//简化形式1;
new Thread(new Runnable() {
@Override
public 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 方法 去获取线程任务执行的结果