美文网首页
线程之创建方式

线程之创建方式

作者: 俗人浮生 | 来源:发表于2019-03-14 20:36 被阅读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(),这一步是阻塞线程的,一直到线程执行完毕返回结果。

    相关文章

      网友评论

          本文标题:线程之创建方式

          本文链接:https://www.haomeiwen.com/subject/zhfhmqtx.html