乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      Future和Callable的使用總結(jié)

       創(chuàng)始元靈6666 2022-06-17 發(fā)布于河北

      在默認(rèn)的情況下,線程Thread對(duì)象不具有返回值的功能,如果在需要取得返回值的情況下是極為不方便的,但在Java1.5的并發(fā)包中可以使用Future和Callable來(lái)使線程具有返回值的功能。

      1.Future和Callable的介紹

      接口Callable與線程功能密不可分,但和Runnable的主要區(qū)別為:

      (1) 接口Callable的call()方法可以有返回值,但Runnable接口的run()方法沒(méi)有返回值。

      (2) Callable接口的call()方法可以聲明拋出異常,而Runnable接口的run()方法不可以聲明拋出異常。

      執(zhí)行完Callable接口中的任務(wù)后,返回值是通過(guò)Future接口進(jìn)行獲得的。

      2.方法get()結(jié)合ExecutorService中的submit(Callable<T>)的使用

      方法submit(Callable<T>)可以執(zhí)行參數(shù)為Callable的任務(wù),方法get()用于獲得返回值,示例如下:

      1. package mycallable;
      2. import java.util.concurrent.Callable;
      3. public class MyCallable implements Callable<String> {
      4. private int age;
      5. public MyCallable(int age) {
      6. super();
      7. this.age = age;
      8. }
      9. public String call() throws Exception {
      10. Thread.sleep(8000);
      11. return "返回值 年齡是:" + age;
      12. }
      13. }
      1. package test.run;
      2. import java.util.concurrent.ExecutionException;
      3. import java.util.concurrent.Future;
      4. import java.util.concurrent.LinkedBlockingDeque;
      5. import java.util.concurrent.ThreadPoolExecutor;
      6. import java.util.concurrent.TimeUnit;
      7. import mycallable.MyCallable;
      8. public class Run {
      9. public static void main(String[] args) throws InterruptedException {
      10. try {
      11. MyCallable callable = new MyCallable(100);
      12. ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 3, 5L,
      13. TimeUnit.SECONDS, new LinkedBlockingDeque());
      14. Future<String> future = executor.submit(callable);
      15. System.out.println("main A " + System.currentTimeMillis());
      16. System.out.println(future.get());
      17. System.out.println("main B " + System.currentTimeMillis());
      18. } catch (ExecutionException e) {
      19. e.printStackTrace();
      20. }
      21. }
      22. }

      3.方法get()結(jié)合ExecutorService中的submit(Runnable)和isDone()的使用

      方法submit()不僅可以傳入Callable對(duì)象,也可以傳入Runnable對(duì)象,說(shuō)明submit方法支持有返回值和無(wú)返回值的功能。如果submit方法傳入Callable接口則可以有返回值,如果傳入Runnable則無(wú)返回值,打印的結(jié)果就是null。方法get()具有阻塞特性,而isDone()方法無(wú)阻塞特性。

      1. package test.run;
      2. import java.util.concurrent.ExecutionException;
      3. import java.util.concurrent.ExecutorService;
      4. import java.util.concurrent.Executors;
      5. import java.util.concurrent.Future;
      6. /**
      7. * 如果submit方法傳入Callable接口則可以有返回值,如果傳入Runnable則無(wú)返回值,打印的結(jié)果就是null。方法get()具有阻塞特性,而isDone()方法無(wú)阻塞特性
      8. * @author linhaiy
      9. * @date 2019.03.06
      10. */
      11. public class Run {
      12. public static void main(String[] args) {
      13. try {
      14. Runnable runnable = new Runnable() {
      15. @Override
      16. public void run() {
      17. System.out.println("打印的信息");
      18. }
      19. };
      20. ExecutorService executorRef = Executors.newCachedThreadPool();
      21. Future future = executorRef.submit(runnable);
      22. System.out.println(future.get() + " " + future.isDone());
      23. } catch (InterruptedException e) {
      24. e.printStackTrace();
      25. } catch (ExecutionException e) {
      26. e.printStackTrace();
      27. }
      28. }
      29. }

      4.使用ExecutorService接口中的方法submit(Runnable,T result)

      方法submit(Runnable,T result)的第2個(gè)參數(shù)result可以作為執(zhí)行結(jié)果的返回值,而不需要使用get()方法來(lái)進(jìn)行獲得。

      1. package entity;
      2. public class Userinfo {
      3. private String username;
      4. private String password;
      5. public Userinfo() {
      6. super();
      7. }
      8. public Userinfo(String username, String password) {
      9. super();
      10. this.username = username;
      11. this.password = password;
      12. }
      13. public String getUsername() {
      14. return username;
      15. }
      16. public void setUsername(String username) {
      17. this.username = username;
      18. }
      19. public String getPassword() {
      20. return password;
      21. }
      22. public void setPassword(String password) {
      23. this.password = password;
      24. }
      25. }
      1. package myrunnable;
      2. import entity.Userinfo;
      3. public class MyRunnable implements Runnable {
      4. private Userinfo userinfo;
      5. public MyRunnable(Userinfo userinfo) {
      6. super();
      7. this.userinfo = userinfo;
      8. }
      9. @Override
      10. public void run() {
      11. userinfo.setUsername("usernameValue");
      12. userinfo.setPassword("passwordValue");
      13. }
      14. }
      1. package test;
      2. import java.util.concurrent.ExecutionException;
      3. import java.util.concurrent.Future;
      4. import java.util.concurrent.FutureTask;
      5. import java.util.concurrent.LinkedBlockingDeque;
      6. import java.util.concurrent.ThreadPoolExecutor;
      7. import java.util.concurrent.TimeUnit;
      8. import myrunnable.MyRunnable;
      9. import entity.Userinfo;
      10. public class Test {
      11. FutureTask abc; //接口Future的實(shí)現(xiàn)類
      12. public static void main(String[] args) {
      13. try {
      14. Userinfo userinfo = new Userinfo();
      15. MyRunnable myrunnable = new MyRunnable(userinfo);
      16. ThreadPoolExecutor pool = new ThreadPoolExecutor(10, 10, 10,
      17. TimeUnit.SECONDS, new LinkedBlockingDeque<Runnable>());
      18. Future<Userinfo> future = pool.submit(myrunnable, userinfo);
      19. System.out.println(future);
      20. System.out.println("begin time=" + System.currentTimeMillis());
      21. userinfo = future.get();
      22. System.out.println("get value " + userinfo.getUsername() + " "
      23. + userinfo.getPassword());
      24. System.out.println(" end time=" + System.currentTimeMillis());
      25. } catch (InterruptedException e) {
      26. e.printStackTrace();
      27. } catch (ExecutionException e) {
      28. e.printStackTrace();
      29. }
      30. }
      31. }

      5.方法cancel(boolean mayInterruptIfRunning) 和isCancelled()的使用

      方法cancel(boolean mayInterruptIfRunning)的參數(shù)mayInterruptIfRunning的作用是:如果線程正在運(yùn)行則是否中斷正在運(yùn)行的線程,在代碼中需要使用if(Thread.currentThread().isInterrupted())進(jìn)行配合。

      方法cancel()的返回值代表發(fā)送取消任務(wù)的命令是否成功完成。

      6.方法get(long timeout,TimeUnit unit)的使用

      方法get(long timeout,TimeUnit unit)的作用是在指定的最大時(shí)間內(nèi)等待獲得返回值。

      1. package mycallable;
      2. import java.util.concurrent.Callable;
      3. public class MyCallable implements Callable<String> {
      4. public String call() throws Exception {
      5. Thread.sleep(10000); //目的是為了在指定時(shí)間內(nèi)獲取不到返回值
      6. System.out.println("sleep 10秒執(zhí)行完了!");
      7. return "anyString";
      8. }
      9. }
      1. package test.run;
      2. import java.util.concurrent.ExecutionException;
      3. import java.util.concurrent.Future;
      4. import java.util.concurrent.LinkedBlockingDeque;
      5. import java.util.concurrent.ThreadPoolExecutor;
      6. import java.util.concurrent.TimeUnit;
      7. import java.util.concurrent.TimeoutException;
      8. import mycallable.MyCallable;
      9. public class Run {
      10. public static void main(String[] args) {
      11. try {
      12. MyCallable callable = new MyCallable();
      13. ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 3, 5L,
      14. TimeUnit.SECONDS, new LinkedBlockingDeque());
      15. System.out.println("begin " + System.currentTimeMillis());
      16. Future<String> future = executor.submit(callable);
      17. System.out.println("返回值" + future.get(5, TimeUnit.SECONDS));
      18. System.out.println(" end " + System.currentTimeMillis());
      19. } catch (InterruptedException e) {
      20. System.out.println("進(jìn)入catch InterruptedException");
      21. e.printStackTrace();
      22. } catch (ExecutionException e) {
      23. System.out.println("進(jìn)入catch ExecutionException");
      24. e.printStackTrace();
      25. } catch (TimeoutException e) {
      26. System.out.println("進(jìn)入catch TimeoutException");
      27. e.printStackTrace();
      28. }
      29. }
      30. }

      7.自定義拒絕策略RejectedExecutionHandler接口的使用

      接口RejectedExecutionHandler的主要作用是當(dāng)線程池關(guān)閉后依然有任務(wù)要執(zhí)行時(shí),可以實(shí)現(xiàn)一些處理。

      1. package com.executionhandler;
      2. import java.util.concurrent.FutureTask;
      3. import java.util.concurrent.RejectedExecutionHandler;
      4. import java.util.concurrent.ThreadPoolExecutor;
      5. public class MyRejectedExecutionHandler implements RejectedExecutionHandler {
      6. public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
      7. System.out.println(((FutureTask) r).toString() + " 被拒絕!");
      8. }
      9. }
      1. package com.executionhandler;
      2. public class MyRunnable implements Runnable {
      3. private String username;
      4. public MyRunnable(String username) {
      5. super();
      6. this.username = username;
      7. }
      8. public void run() {
      9. System.out.println(username + " 在運(yùn)行!");
      10. }
      11. }
      1. package com.executionhandler;
      2. import java.util.concurrent.ExecutorService;
      3. import java.util.concurrent.Executors;
      4. import java.util.concurrent.ThreadPoolExecutor;
      5. public class Run {
      6. public static void main(String[] args) {
      7. ExecutorService service = Executors.newCachedThreadPool();
      8. ThreadPoolExecutor executor = (ThreadPoolExecutor) service;
      9. executor.setRejectedExecutionHandler(new MyRejectedExecutionHandler());
      10. service.submit(new MyRunnable("A"));
      11. service.submit(new MyRunnable("B"));
      12. service.submit(new MyRunnable("C"));
      13. executor.shutdown();
      14. service.submit(new MyRunnable("D"));
      15. }
      16. }

      8.方法execute()與submit()的區(qū)別

      (1) 方法execute()沒(méi)有返回值,而submit()方法可以有返回值。

      (2) 方法execute()在默認(rèn)的情況下異常直接拋出,不能捕獲,但可以通過(guò)自定義ThreadFactory的方式進(jìn)行捕獲,而submit()方法在默認(rèn)的情況下,可以catch Execution-Exeception捕獲異常

      9.驗(yàn)證Future的缺點(diǎn)

      1. package mycallable;
      2. import java.util.concurrent.Callable;
      3. public class MyCallable implements Callable<String> {
      4. private String username;
      5. private long sleepValue;
      6. public MyCallable(String username, long sleepValue) {
      7. super();
      8. this.username = username;
      9. this.sleepValue = sleepValue;
      10. }
      11. @Override
      12. public String call() throws Exception {
      13. System.out.println(username);
      14. Thread.sleep(sleepValue);
      15. return "return " + username;
      16. }
      17. }
      1. package test;
      2. import java.util.ArrayList;
      3. import java.util.List;
      4. import java.util.concurrent.Callable;
      5. import java.util.concurrent.ExecutionException;
      6. import java.util.concurrent.Future;
      7. import java.util.concurrent.LinkedBlockingDeque;
      8. import java.util.concurrent.ThreadPoolExecutor;
      9. import java.util.concurrent.TimeUnit;
      10. import mycallable.MyCallable;
      11. public class Test {
      12. public static void main(String[] args) {
      13. try {
      14. MyCallable callable1 = new MyCallable("username1", 5000);
      15. MyCallable callable2 = new MyCallable("username2", 4000);
      16. MyCallable callable3 = new MyCallable("username3", 3000);
      17. MyCallable callable4 = new MyCallable("username4", 2000);
      18. MyCallable callable5 = new MyCallable("username5", 1000);
      19. List<Callable> callableList = new ArrayList<Callable>();
      20. callableList.add(callable1);
      21. callableList.add(callable2);
      22. callableList.add(callable3);
      23. callableList.add(callable4);
      24. callableList.add(callable5);
      25. List<Future> futureList = new ArrayList<Future>();
      26. ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 10, 5, TimeUnit.SECONDS,
      27. new LinkedBlockingDeque<Runnable>());
      28. for (int i = 0; i < 5; i++) {
      29. futureList.add(executor.submit(callableList.get(i)));
      30. }
      31. System.out.println("run first time= " + System.currentTimeMillis());
      32. for (int i = 0; i < 5; i++) {
      33. System.out.println(futureList.get(i).get() + " " + System.currentTimeMillis());
      34. }
      35. // 按順序打印的效果
      36. // 說(shuō)明一個(gè)Future對(duì)應(yīng)指定的一個(gè)Callable
      37. } catch (InterruptedException e) {
      38. e.printStackTrace();
      39. } catch (ExecutionException e) {
      40. e.printStackTrace();
      41. }
      42. }
      43. }

      總結(jié):Future和Callable這兩個(gè)接口的優(yōu)點(diǎn)就是從線程中返回?cái)?shù)據(jù)以便進(jìn)行后期的處理,但是FutureTask類也有其自身的缺點(diǎn),就是阻塞性。

        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類似文章 更多