线程之创建方式

2019-03-14  本文已影响0人  俗人浮生

面试题:线程的创建方式有哪几种?
想都没想就答:有两种,一种是直接继承Thread类,一种是实现Runnable接口
面试官:Any more?
我:这·······

其实,还有一种叫做Callable,看起来跟Runnable有点像,但还是有区别的,我们还是直接上例子吧:

       //第1种Thread
       Thread thread=new Thread(){
            @Override
            public void run() {
                super.run();
                System.out.println("当前线程1:"+Thread.currentThread().getName());
            }
        };
        thread.start();

        //第2种Runnable
        Runnable runnable=new Runnable() {
            @Override
            public void run() {
                System.out.println("当前线程2:"+Thread.currentThread().getName());
            }
        };
        new Thread(runnable).start();

        //第3种Runnable
        Callable<String> callable=new Callable<String>() {
            @Override
            public String call() throws Exception {
                System.out.println("当前线程3:"+Thread.currentThread().getName());
                Thread.sleep(2000);
                return "你好吗?";
            }
        };
        FutureTask<String> futureTask=new FutureTask<>(callable);
        new Thread(futureTask).start();
        try {
            String s = futureTask.get();//阻塞线程,2秒后才返回结果
            System.out.println("输出结果:"+ s);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }

前面两种没什么好说的,我们来看看Runnable和Callable的区别:
1、最大的区别:Callable有返回值,Runnable没有返回值
2、Callable中的call方法允许 throws Exception,Runnable中的异常只能自己处理,不能上抛

我们重点来看看Callable,从上面的区别我们可以知道,其实引入了Callable最大的好处就是我们可以获取到线程执行的结果,上面的例子也正好说明这一点。
说到Callable,总免不了要说Future和FutureTask,我们来看看Future的源码:

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;
}

它是一个泛型接口,从它的方法我们可以直接,它提供了3个主要的功能:
1)判断任务是否完成;
2)能够中断任务;
3)能够获取任务执行结果。
而FutureTask是Future接口的一个唯一实现类,所以,我们上面用的就是FutureTask。
需要注意一点,拿上面例子来说吧: String s = futureTask.get(),这一步是阻塞线程的,一直到线程执行完毕返回结果。

上一篇下一篇

猜你喜欢

热点阅读