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;@Overridepublic String call() throws Exception {// TODO Auto-generated method stubString 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();
}