创建方式
- 继承Thread类
Thread 类本质上是实现了 Runnable 接口的一个实例,代表一个线程的实例。启动线程的唯一方法就是
通过 Thread 类的 start()实例方法。start()方法是一个 native 方法,它将启动一个新线程,并执行run()方
法
public class MyThread extends Thread {
public void run() {
System.out.println("MyThread.run()");
}
}
MyThread myThread1 = new MyThread();
myThread1.start();
- 实现Runnable接口
如果自己的类已经 extends 另一个类,就无法直接 extends Thread,此时,可以实现一个 Runnable
接口。
public class MyThread extends OtherClass implements Runnable {
public void run() {
System.out.println("MyThread.run()");
}
}
//启动 MyThread,需要首先实例化一个 Thread,并传入自己的 MyThread 实例:
MyThread myThread = new MyThread();
Thread thread = new Thread(myThread);
thread.start();
//事实上,当传入一个 Runnable target 参数给 Thread 后,Thread 的 run()方法就会调用
target.run()
public void run() {
if (target != null) {
target.run();
}
}
- 实现 Callable 接口
创建一个实现callable的实现类
实现call方法,将此线程需要执行的操作声明在call()中
创建callable实现类的对象
将callable接口实现类的对象作为传递到FutureTask的构造器中,创建FutureTask的对象
将FutureTask的对象作为参数传递到Thread类的构造器中,创建Thread对象,并调用start方法启动
public class ThirdThreadImp {
public static void main(String[] args) {
//这里call()方法的重写是采用lambda表达式,没有新建一个Callable接口的实现类
FutureTask<Integer> task = new FutureTask<Integer>((Callable<Integer>)()->{
int i = 0;
for(;i < 50;i++) {
System.out.println(Thread.currentThread().getName() +
" 的线程执行体内的循环变量i的值为:" + i);
}
//call()方法的返回值
return i;
});
for(int j = 0;j < 50;j++) {
System.out.println(Thread.currentThread().getName() +
" 大循环的循环变量j的值为:" + j);
if(j == 20) {
new Thread(task,"有返回值的线程").start();
}
}
try {
System.out.println("子线程的返回值:" + task.get());
} catch (Exception e) {
e.printStackTrace();
}
}
}
runnable()与callaalbe()对比
runnable重写的run方法不如callaalbe的call方法强大,call方法可以有返回值
方法可以抛出异常
支持泛型的返回值
需要借助FutureTask类,比如获取返回结果
如果任务不需要返回结果或抛出异常推荐使用Runnable接口,这样代码看起来会更加简洁。