java可以通过继承Thread、实现Runnable接口、实现Callable接口来实现多线程
- 因为
继承Thread
、实现Runnable
、用FutureTask包装Callable
本质上都是Runnable的实例,所以都可以用new Thread(Runnable target).start()
来启动线程。 继承Thread
、实现Runnable
不能返回结果,用FutureTask包装Callable
可以返回结果。
Thread 实现了 Runnable 接口,本质上还是一个 Runnable 接口
public class Thread implements Runnable {
public Thread(Runnable target) {...}
public synchronized void start() {...} // 启动线程
...
}
通过继承 Thread
类来创建线程
public class ThreadInstance extends Thread {
String message;
public ThreadInstance(String message) {
this.message = message;
}
@Override
public void run() {
System.out.println(message);
}
public static void main(String[] args) {
Runnable threadInstance = new ThreadInstance("hello world");
new Thread(threadInstance).start();
}
}
Runnable接口
@FunctionalInterface
public interface Runnable {
public abstract void run();
}
通过实现Runnable
接口重写run()
来创建线程:
public class RunnableInstance implements Runnable {
String message;
public RunnableInstance(String message) {
this.message = message;
}
@Override
public void run() {
System.out.println(message);
}
public static void main(String[] args) {
Runnable runnableInstance = new ThreadInstance("hello world");
new Thread(runnableInstance).start();
// new Thread(() -> System.out.println("hello world")).start(); lambda写法
}
}
Callable 接口
@FunctionalInterface
public interface Callable<V> {
V call() throws Exception;
}
FutureTask 类,本质上还是Runnable,所以可以使用 Thread(Runnable target).start() 来启动线程
public class FutureTask<V> implements RunnableFuture<V> {
public FutureTask(Callable<V> callable) {
...
}
public FutureTask(Runnable runnable, V result) {
...
}
}
public interface RunnableFuture<V> extends Runnable, Future<V> {
void run();
}
public interface Future<V> {
boolean cancel(boolean mayInterruptIfRunning);
boolean isCancelled();
boolean isDone();
V get() throws InterruptedException, ExecutionException;
V get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException;
}
通过实现Callable
接口重写call()
来创建线程:
public class CallableInstance implements Callable<Integer> {
@Override
public Integer call() {
System.out.println("hello world");
return 6;
}
public static void main(String[] args) {
CallableInstance callableInstance = new CallableInstance();
FutureTask<Integer> integerFutureTask = new FutureTask<>(callableInstance);
new Thread(integerFutureTask).start();
try {
System.out.println(integerFutureTask.get());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
}