#Callable接口java
public interface Callable<V> { V call() throws Exception; }
#Runnable接口多线程
public interface Runnable { public abstract void run(); }
都是接口dom
均可以编写多线程程序异步
都采用Thread.start()启动线程ide
Runnable没有返回值;Callable能够返回执行结果,是个泛型,和Future、FutureTask配合能够用来获取异步执行的结果spa
Callable接口的call()方法容许抛出异常;Runnable的run()方法异常只能在内部消化,不能往上继续抛线程
注:Callalbe接口支持返回执行结果,须要调用FutureTask.get()获得,此方法会阻塞主进程的继续往下执行,若是不调用不会阻塞。code
#Callable-1blog
import java.util.Random; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.FutureTask; public class CallableAndFuture { public static void main(String[] args) { Callable<Integer> callable = new Callable<Integer>() { @Override public Integer call() throws Exception { Thread.sleep(6000); return new Random().nextInt(); } }; FutureTask<Integer> future = new FutureTask<>(callable); new Thread(future).start(); try { Thread.sleep(1000); System.out.println("hello begin"); System.out.println(future.isDone()); System.out.println(future.get()); System.out.println(future.isDone()); System.out.println("hello end"); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } } }
结果接口
hello begin false 1664014921 true hello end
#Callable-2
import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.FutureTask; public class CallableThreadTest implements Callable<Integer> { public static void main(String[] args) throws ExecutionException, InterruptedException { CallableThreadTest ctt = new CallableThreadTest(); FutureTask<Integer> ft = new FutureTask<>(ctt); new Thread(ft, "有返回值的线程").start(); System.out.println("子线程的返回值" + ft.get()); } @Override public Integer call() { int i; for (i = 0; i < 10; i += 2) { System.out.println(Thread.currentThread().getName() + " " + i); } return i; } }
结果
有返回值的线程 0 有返回值的线程 2 有返回值的线程 4 有返回值的线程 6 有返回值的线程 8 子线程的返回值10
多线程返回执行结果是颇有用的一个特性,由于多线程相比单线程更难、更复杂的一个重要缘由就是由于多线程充满着未知性,某条线程是否执行了?某条线程执行了多久?某条线程执行的时候咱们指望的数据是否已经赋值完毕?没法得知,咱们能作的只是等待这条多线程的任务执行完毕而已。而Callable+Future/FutureTask却能够获取多线程运行的结果,能够在等待时间太长没获取到须要的数据的状况下取消该线程的任务,真的是很是有用。
public class CallableAndFuture { public static void main(String[] args) { Callable<Integer> callable = new Callable<Integer>() { @Override public Integer call() throws Exception { Thread.sleep(6000); return new Random().nextInt(); } }; FutureTask<Integer> future = new FutureTask<>(callable); new Thread(future).start(); try { Thread.sleep(1000); System.out.println("hello begin"); System.out.println(future.isDone()); // future.cancel(false); if (!future.isCancelled()) { System.out.println(future.get()); System.out.println(future.isDone()); System.out.println("hello end"); } else { System.out.println("cancel~"); } } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } } }