写在前面:
Java 实现多线程共有3种方式,第一种是继承Thread类,第二种是实现Runnable接口,而在Java5之后,又增加了第三种方式,实现Callable接口。
- 继承Thread类:
package createthread;
public class Demo1 {
public static void main(String[] args) {
ThreadDemo thread1 = new ThreadDemo();
thread1.start();
}
}
class ThreadDemo extends Thread {
public void run() {
System.out.print("thread1");
}
}
- 实现Runnable接口
package createthread;
public class Demo2 {
public static void main(String[] args) {
ThreadDemo3 demo = new ThreadDemo3();
Thread thread1 = new Thread(demo);
thread1.start();
}
}
class ThreadDemo3 implements Runnable {
@Override
public void run() {
System.out.println("实现Runnable接口方式");
}
}
与直接继承Thread不同,实现Runnable接口的方式,在调用时,我们仍然要先创建一个Thread实例,这种做的好处是,由于Java支持单继承,多实现,避免线程类继承了Thread,就不能继承其他类了。
- 实现Callable接口:
要想使用Callable接口,分为以下几个步骤:
(1)创建一个Callable的实现类,并且实现call方法
(2)创建Callable实现类的实现,使用FutureTask类来包装一个Callable对象,这个FutureTask类的实例封装了Callable对象run方法的返回值。
(3)使用FutureTask对象作为Thread对象的target,创建并启动线程。
(4)调用FutureTask对象的get方法来获取子线程结束的返回值。
Demo:
package createthread;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class Demo3 {
public static void main(String[] args) throws InterruptedException, ExecutionException {
Callable<Integer> call = new ThreadDemo4();
FutureTask<Integer> task = new FutureTask<Integer>(call);
Thread thread = new Thread(task);
thread.start();
System.out.println(task.get());
}
}
class ThreadDemo4 implements Callable<Integer> {
@Override
public Integer call() throws Exception {
System.out.println("Callable实现");
return 7;
}
}
控制台输出:
Callable实现
7
总结:
三种方式对比之下,继承Thread类不如实现Runnable接口,因为Java支持单继承,多实现,避免线程类继承了Thread,就不能继承其他类了。
实现Callable接口,可以满足,在线程执行结束时,会返回一个值的需求。