Future和 callable API的使用

    科技2022-07-13  140

    callable与runnable的区别 1 callable接口的call()方法有返回值,而runnable的run()没有。 2 callable接口的call()方法可以声明抛出异常,而runnable的run()不可以。

    V get() throws InterruptedException, ExecutionException; 获取线程执行的返回结果,具有阻塞性。 V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException; 在指定的最大时间内获取到返回值,超时抛出异常。 boolean isDone(); 获取线程是否执行,无阻塞性。 ExecutorService接口中的 Future submit(Callable task) 方法提交线程执行,传入callable有返回值,传入runnable无返回值,若用get()获取则为null;

    import java.util.concurrent.Callable; public class MyCallable implements Callable<String> { @Override public String call() throws Exception { Thread.sleep(1000); return "callable call result 100"; } } public static void main(String[] args) { MyCallable myCallable = new MyCallable(); ThreadPoolExecutor pool = new ThreadPoolExecutor(2,3,5,TimeUnit.SECONDS,new LinkedBlockingDeque()); System.out.println("start "+System.currentTimeMillis()); Future<String> future = pool.submit(myCallable); try { System.out.println("get "+future.get()+" isDone "+future.isDone()); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ExecutionException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("end "+System.currentTimeMillis()); }

    测试结果 start 1601779382721 get callable call result 100 isDone true end 1601779383723

    ExecutorService接口中的 Future submit(Runnable task, T result)

    public class MyRunnableUser implements Runnable { private UserInfo userInfo; public MyRunnableUser(UserInfo userInfo) { super(); this.userInfo = userInfo; } @Override public void run() { userInfo.setPassword("123"); userInfo.setUserName("pys"); } } public static void main(String[] args) { UserInfo userInfo = new UserInfo(); MyRunnableUser myRunnableUser = new MyRunnableUser(userInfo); ThreadPoolExecutor pool = new ThreadPoolExecutor(2, 3, 5, TimeUnit.SECONDS, new LinkedBlockingDeque<Runnable>()); Future<UserInfo> future = pool.submit(myRunnableUser,userInfo); System.out.println("start "+System.currentTimeMillis()); try { userInfo=future.get(); System.out.println("value "+userInfo.getUserName()+" "+userInfo.getPassword()); System.out.println("end "+System.currentTimeMillis()); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ExecutionException e) { // TODO Auto-generated catch block e.printStackTrace(); } }

    测试结果 start 1601779819114 value pys 123 end 1601779819114

    boolean cancel(boolean mayInterruptIfRunning); 发送取消任务指令,返回值代表消息发送是否成功,不能代表任务有没有取消成功,参数mayInterruptIfRunning具有线程中断效果,true具有中断线程的效果,需要结合if(Thread.currentThread().isInterrupted())使用。 boolean isCancelled(); 返回任务是否取消成功。

    public class MyCallableCancel implements Callable<String> { @Override public String call() throws Exception { while(1==1) { if(Thread.currentThread().isInterrupted()) { throw new InterruptedException(); } System.out.println("线程运行中"); } } } public static void main(String[] args) { MyCallableCancel myCallableCancel = new MyCallableCancel(); ThreadPoolExecutor pool = new ThreadPoolExecutor(2, 3, 5, TimeUnit.SECONDS, new LinkedBlockingDeque()); Future<String> future = pool.submit(myCallableCancel); try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("cancel "+future.cancel(true)+" isCancel "+future.isCancelled()); }

    future.cancel(true) 测试结果 线程中断,任务取消 线程运行中 线程运行中 线程运行中 cancel true isCancel true

    future.cancel(false) 测试结果 线程没有中断, 任务没有取消 线程运行中 线程运行中 线程运行中 cancel true isCancel true 线程运行中 线程运行中 线程运行中

    自定义的拒接策略 RejectedExecutionHandler

    public class MyReject implements RejectedExecutionHandler { @Override public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { System.out.println(r.toString()+" 自定义拒绝策略执行"); } } public static void main(String[] args) { ExecutorService service = Executors.newCachedThreadPool(); ThreadPoolExecutor pool = (ThreadPoolExecutor) service; pool.setRejectedExecutionHandler(new MyReject()); pool.submit(new MyRunnable("A")); pool.submit(new MyRunnable("B")); pool.submit(new MyRunnable("C")); pool.shutdown(); pool.submit(new MyRunnable("D")); }

    测试结果 B 在运行 A 在运行 C 在运行 java.util.concurrent.FutureTask@55f96302 自定义拒绝策略执行

    方法execute()与submit()的区别 1 execute() 没有返回值,submit()有返回值。 2 execute()默认情况下异常直接抛出不能捕获,可以通过自定义Thread-Factory的自定义异常处理方式进行捕获,submit()默认情况下可以自己捕获异常。

    Processed: 0.017, SQL: 8