每次看到Runnable和Callable都会忘记两者的一些区别,感觉两者比较像,想想是时候来一波博客来记录记录,提醒一下自己。
话不多说,先抛两个简单的例程抛砖引玉:
1.Runnable例程
package RunnableAndCallable;
/**
* Created by jiangxs on 17-4-24.
*/
public class RunnableImp implements Runnable{
private String str;
RunnableImp(String str){
this.str = str;
}
@Override
public void run(){
try {
//线程休眠1000毫秒,1000毫秒后继续执行,发生的异常不能抛出,需在内部处理
Thread.sleep(1000);
}catch (Exception e){
e.printStackTrace();
}
System.out.println( "please add String : "+str);
}
public static void main(String[] args) {
//主线程不会发生阻塞
//开始时间
long start = System.currentTimeMillis();
//创建线程并启动线程
new Thread(new RunnableImp("Runnable Test")).start();
//结束时间
long end = System.currentTimeMillis();
System.out.println("End : "+(end - start)+"毫秒");
}
}
测试结果:
End : 0毫秒
please add String : Runnable Test
Process finished with exit code 0
2.Callable例程
package RunnableAndCallable;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
/**
* Created by jiangxs on 17-4-24.
*/
public class CallableImp implements Callable<String>{
private String str ;
CallableImp(String str){
this.str = str;
}
@Override
public String call() throws Exception{
//线程休眠1000毫秒,1000毫秒后继续执行,发生的异常可以进行抛出
Thread.sleep(1000);
return "please add String : "+str;
}
public static void main(String[] args) throws ExecutionException,InterruptedException{
Callable<String> callable = new CallableImp("Callable Test");
FutureTask<String> ft = new FutureTask<String>(callable);
//开始时间
long start = System.currentTimeMillis();
//创建线程并启动线程
new Thread(ft).start();
//调用ft.get()方法阻塞主线程,不调用则不产生阻塞作用
String str = ft.get();
//结束时间
long end = System.currentTimeMillis();
System.out.println("Start : "+str);
System.out.println("End : "+(end - start)+"毫秒");
}
}
测试结果:
Start : please add String : Callable Test
End : 1001毫秒
Process finished with exit code 0
根据上面的两个例程可以看出Runnable和Callable这两个接口的共同点:都可以实现多线程,并且创建多线程的方式均是Thread.start()
由此可以总结两者的区别:
(1)由上面的例子我们可以看看Runnable和Callable这两个接口:
public interface Runnable{
public abstract void run();
}
public interface Callable<V>{
v call() throws Exception;
}
这两个接口实现的方法不同,Runnable实现的是void run()方法,而Callable实现的是V call()方法。call()方法可以返回执行结果,而run()方法没有返回值。
(2)Callable有返回结果,而Runnable无返回结果,即使通过Future也看不到任务调度结果。
(3)call()方法可以抛出受检查的异常,而run()方法不能抛出受检查的异常。