面试题:callable与runable的区别?
Callable和Runnable是Java中用于创建线程和执行任务的两种不同的接口,他们之间有几个关键的区别:
1.返回值:
Runnable接口定义了一个无返回值的run()方法。这意味着你无法从执行run()方法的线程获取任何结果。
Callable接口定义了一个call()方法,此方法可以返回一个泛型类型的结果。你可以通过Future对象获取这个结果。
2.异常处理:
Runnable的run()方法不能声明抛出受检查异常(checked execeptions)。任何run()方法重抛出的受检查异常都会被封装成UndelaredThrowableError或UndeclaredRuntimeException,并由JVM自动处理。
Callable的call()方法可以声明抛出收检查异常。调用者可以调用Future.get()方法处理这些异常,
3.使用方式:
实现Runnable
的类可以直接传递给Thread
的构造函数,然后通过Thread.start()
方法启动线程。
实现Callable
的类不能直接用来创建Thread
对象,需要借助FutureTask
包装器。FutureTask
是一个包装器类,它同时实现了Runnable
和Future
接口,允许我们通过Future
的API来管理 callable 任务,包括获取结果和取消执行等。创建了FutureTask
之后,可以像使用Runnable
那样将它传递给Thread
,或者提交给ExecutorService
来执行。
4.结果获取:
由于Runnable
没有返回值,所以没有直接的方式获取执行结果。
对于Callable
任务,通过FutureTask.get()
方法可以获取到线程执行结束后的结果,这个方法会阻塞直到结果可用。
5.总结:
总结来说,如果你需要线程执行后返回一个结果或者需要能够抛出和处理检查型异常,你应该使用Callable
接口配合FutureTask
;如果不需要返回结果且不需要处理特定的异常,使用Runnable
接口会更加简单。