02-创建线程的三种方式
废话不说,直接上代码
继承Thread类
// 继承Thread
class MyThread extends Thread {
// 重写run方法执行任务
@Override
public void run() {
for (int i = 0; i < 10; i++) {
// 可以通过this拿到当前线程
System.out.println(this.getName()+"执行了"+i);
}
}
}
public class Demo_02_02_1_ThreadCreateWays {
public static void main(String[] args) {
// 先new出来,然后启动
MyThread myThread = new MyThread();
myThread.start();
for (int i = 0; i < 10; i++) {
// 通过Thread的静态方法拿到当前线程
System.out.println(Thread.currentThread().getName()+"执行了"+i);
}
}
}
实现Runnable
// 实现Runnable接口
class MyThreadByRunnable implements Runnable {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
// 不能用this了
System.out.println(Thread.currentThread().getName() + "执行了" + i);
}
}
}
public class Demo_02_02_1_ThreadCreateWays {
public static void main(String[] args) {
// 实现Runnable接口的方式启动线程
Thread thread = new Thread(new MyThreadByRunnable());
thread.start();
for (int i = 0; i < 10; i++) {
// 通过Thread的静态方法拿到当前线程
System.out.println(Thread.currentThread().getName() + "执行了" + i);
}
}
}
用lamba也可以
new Thread(() -> {
System.out.println("Runnable是函数式接口, java8也可以使用lamba");
}).start();
使用Callable和Future
// 使用Callable
class MyThreadByCallable implements Callable<Integer> {
@Override
public Integer call() throws Exception {
int sum = 0;
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName()+"执行了"+i);
sum+=i;
}
return sum;
}
}
public class Demo_02_02_1_ThreadCreateWays {
public static void main(String[] args) {
// 用FutureTask包一层
FutureTask<Integer> futureTask = new FutureTask<>(new MyThreadByCallable());
new Thread(futureTask).start();
try {
// 调用futureTask的get能拿到返回的值
System.out.println(futureTask.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
这是最复杂的一种方式,他可以有返回值,归纳一下步骤:
搞一个类实现
Callable
接口,重写call
方法,在call
执行任务用
FutureTask
包装实现Callable
接口类的实例将
FutureTask
的实例作为Thread
构造参数调用
FutureTask
实例的get
拿到返回值,调这一句会阻塞父线程
Callable
也是函数式接口,所以也能用lamba
为啥Thread构造里边能方Runnable,也能放FutureTask? 其实FutureTask继承RunnableFuture,而RunnableFuture继承Runnable和Future,注意接口是可以多继承的
三种方式比较
方式
使用简易程度
是否可以共享任务代码
是否可以有返回值
是否可以声明抛出异常
是否可以再继承别的类
继承Thread
简单
不能
不能
不能
不能
Runnable
中等
可以
不能
不能
可以
Callable
复杂
可以
可以
可以
可以
继承Thread
是最容易的,但是也是最不灵活的
使用Callable
时最复杂的,但是也是最灵活的
这里说的共享任务代码举个例子:
还是上面那个MyThreadByRunnable
类
MyThreadByRunnable myThreadByRunnable = new MyThreadByRunnable();
Thread thread = new Thread(myThreadByRunnable);
thread.start();
// 再来一个,复用了任务代码,继承Thread就不行
Thread thread2 = new Thread(myThreadByRunnable);
thread2.start();
最后更新于
这有帮助吗?