多线程编程之Runnable与Callable区别
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多线程编程之Runnable与Callable区别相关的知识,希望对你有一定的参考价值。
Runnable
@FunctionalInterface
public interface Runnable {
/**
* When an object implementing interface <code>Runnable</code> is used
* to create a thread, starting the thread causes the object‘s
* <code>run</code> method to be called in that separately executing
* thread.
* <p>
* The general contract of the method <code>run</code> is that it may
* take any action whatsoever.
*
* @see java.lang.Thread#run()
*/
public abstract void run();
}
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;
}
相同点:
1.都是接口,都能够实现多线程编程,都需要Thread.start()来启动线程。
不同点:
1.Callable接口支持返回执行结果,此时需要调用FutureTask.get()方法实现,此方法会阻塞主线程直到获取‘将来’结果;当不调用此方法时,主线程不会阻塞!
Callable使用
/**
* CallableImpl 简要描述
* <p> TODO:描述该类职责 </p>
*
* @author ckmike
* @version 1.0
* @date 18-12-6 下午8:53
* @copyright ckmike
**/
public class CallableImpl implements Callable<String> {
private String accept;
public CallableImpl(String accept) {
this.accept = accept;
}
@Override
public String call() throws Exception {
// 休眠
TimeUnit.SECONDS.sleep(3);
return this.accept;
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
Callable<String> callable = new CallableImpl("my callable test!");
FutureTask<String> task = new FutureTask<>(callable);
long beginTime = System.currentTimeMillis();
// 创建线程
new Thread(task).start();
// 调用get()阻塞主线程,反之,线程不会阻塞
String result = task.get();
long endTime = System.currentTimeMillis();
System.out.println("hello : " + result);
System.out.println("cast : " + (endTime - beginTime) / 1000 + " second!");
}
}
Runnable使用
/**
* RunnableImpl 简要描述
* <p> TODO:描述该类职责 </p>
*
* @author ckmike
* @version 1.0
* @date 18-12-6 下午9:03
* @copyright ckmike
**/
public class RunnableImpl implements Runnable {
public RunnableImpl(String accept) {
this.accept = accept;
}
private String accept;
@Override
public void run() {
// 线程阻塞 1 秒,此时有异常产生,只能在方法内部消化,无法上抛
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 最终处理结果无法返回
System.out.println("hello : " + this.accept);
}
public static void main(String[] args) {
Runnable runnable = new RunnableImpl("my runable test!");
long beginTime = System.currentTimeMillis();
new Thread(runnable).start();
long endTime = System.currentTimeMillis();
System.out.println("cast : " + (endTime - beginTime) / 1000 + " second!");
}
}
写这篇文章的原因是:面试时问道Runnable与Callable的区别,平时也就用Runnable比较多,基本上没有用过Callable,所以就挂了,哈哈哈,也总结给有需要的朋友。有知道Callable接口的使用场景吗?有的话可以留意分享给我吗?谢谢了!
以上是关于多线程编程之Runnable与Callable区别的主要内容,如果未能解决你的问题,请参考以下文章