Runnable和Callable接口辨析

突然发现和启动一个线程有关的有三函数,run(), call(), start(),有点小乱,所以特别梳理一下

首先说一下start(),这个是最好说的,感觉start()run()这俩名字是真的有点容易混

其实,start()是我们用extends Thread方式写一个线程才会遇到的问题,其中的逻辑就是,start()会调用run()方法,就run()方法自己而言,其实就是一个同步的方法,所以如果在main中直接调用一个线程的run方法,会看到多个线程会顺序执行。

只有用start方法开始线程,才能真正异步执行

上面只是简单提一下,下面说这篇文章的重点内容

Runnable 和 Callable 有什么区别呢

其实看一下run()call()的接口就知道了

public void run();
public Object call() throws Exception;

一个有返回值,一个没有。然而没这么简单,当我们要用他的返回值的时候,问题就出现了。

在说返回值之前,先简单说一下Callable实现的线程怎么启动

Callable tt2 = new t2();
FutureTask task = new FutureTask<Integer>(tt2);
new Thread(task).start();

其中FutureTask就是返回值的类型,这里是如何启动Callable线程,还有其他的线程池方法,会在今后介绍线程池的时候讲解

下面就要说会发生什么问题了,其实就是我们可以通过get方法来获得线程的返回值,但是,在我们调用get的时候,如果线程尚未返回,那么调用者线程将会被阻塞,直到获取返回值

Callable tt2 = new t2();
FutureTask task = new FutureTask<Integer>(tt2);
task.get()
new Thread(task).start();

上面就是一个简单的死锁的例子,相信聪明的你一定理解我的意思了


个人的理解是Callable线程更多地被应用在并行结算等场合上,而不是处理业务逻辑上,所以Callable线程往往应该更短一些,同时可以一次启动多个,以便快速地获得相应的返回值

猜你喜欢

转载自www.cnblogs.com/Nocturne/p/10747137.html