java 中创建多线程最常见的是继承Thread 的子类重写run() 方法,还有就是实现Runnable 接口
我们最好使用实现了Runnable 接口的方法原因有两点:
①因为java 的单继承的特点,所以说使用第一种方法不能继承其他父类了
②采用接口的方式便于实现数据共享,线程的启动需要Thread类的start方法,如果采用继承的方式每次新建一个线程时,每个新建线程的数据都会单独的存在线程内存中,这样每个线程会单独的操作自己线程的数据,不能更好的实现线程之间的数据共享)
如果我们想要我们的线程有返回值,那么我们可以实现Callable 接口
@FunctionalInterface
public interface Callable<V> {
/**
* Computes a result, or throws an exception if unable to do so.
*
* @return computed result
* @throws Exception if unable to compute a result
*/
V call() throws Exception;
}
这里我传入了一个String类型作为接口call方法的返回值类型,然后实现了call方法,将result作为返回结果返回。
public class MyCallable<String> implements Callable<String> {
private int tickt=10;
@Override
public String call() throws Exception {
// TODO Auto-generated method stub
String result;
while(tickt>0) {
System.out.println("票还剩余:"+tickt);
tickt--;
}
result=(String) "票已卖光";
return result;
}
}
采用实现Callable接口实现多线程启动方式和以往两种的方式不太一样,下面就看一下怎样启动采用实现Callable接口的线程,首先我 new 一个我的实现实例,然后将我生成的实例对象注册进入到FutureTask类中,然后将FutureTask类的实例注册进入Thread中运行。最后可以采用FutureTask中的get方法获取自定义线程的返回值。
public static void main(String[] args) throws InterruptedException, ExecutionException {
MyCallable<String> mc=new MyCallable<String>();
FutureTask<String> ft=new FutureTask<String>(mc);
new Thread(ft).start();
String result=ft.get();
System.out.println(result);
}
看一下FutureTask 类的源码实现
public class FutureTask<V> implements RunnableFuture<V>{
public FutureTask(Callable<V> callable) {
if (callable == null)
throw new NullPointerException();
this.callable = callable;
this.state = NEW; // ensure visibility of callable
}
}
再来看一下RunnableFuture 的底层实现
public interface RunnableFuture<V> extends Runnable, Future<V> {
/**
* Sets this Future to the result of its computation
* unless it has been cancelled.
*/
void run();
}