java并发包:future模式

叁歲伎倆 2024-02-17 21:18 193阅读 0赞

本文转载至:http://blog.csdn.net/a910626/article/details/51900972

future模式是多线程开发中非常常见的一种设计模式,它的核心思想是异步调用。当我们需要调用一个函数方法时,如果这个函数执行很慢,那么我们就要进行等待。但有时候我们可能并不着急着要结果。因此,我们可以让被调用者立即返回,让他在后台慢慢处理这个请求。对于调用者来说,则可以先处理一些其他任务,在真正需要数据的场合再去尝试获得需要的数据。

  Future模式有点类似于商品订单。在网上购物时,提交订单后,在收货的这段时间里无需一直在家里等候,可以先干别的事情。类推到程序设计中时,当提交请求时,期望得到答复时,如果这个答复可能很慢。传统的时一直等待到这个答复收到时再去做别的事情,但如果利用Future设计模式就无需等待答复的到来,在等待答复的过程中可以干其他事情。

  对于future模式来说,虽然它无法立即给你需要的数据。但是,它会返回给你一个契约,将来,你可以凭借这个契约去重新获取你需要的信息。

Future模式java实现

futurejava.png

(1) Data.Java

  1. public interface Data {
  2. public String getResult();
  3. }
  4. 1
  5. 2
  6. 3
  7. 1
  8. 2
  9. 3

(2) RealData.java

  1. public class RealData implements Data {
  2. protected final String result;
  3. public RealData(String para) {
  4. //RealData的构造可能很慢,需要用户等待很久
  5. StringBuffer sb=new StringBuffer();
  6. for (int i = 0; i < 10; i++) {
  7. sb.append(para);
  8. try {
  9. Thread.sleep(100);
  10. } catch (InterruptedException e) {
  11. }
  12. }
  13. result=sb.toString();
  14. }
  15. public String getResult() {
  16. return result;
  17. }
  18. }
  19. 1
  20. 2
  21. 3
  22. 4
  23. 5
  24. 6
  25. 7
  26. 8
  27. 9
  28. 10
  29. 11
  30. 12
  31. 13
  32. 14
  33. 15
  34. 16
  35. 17
  36. 18
  37. 1
  38. 2
  39. 3
  40. 4
  41. 5
  42. 6
  43. 7
  44. 8
  45. 9
  46. 10
  47. 11
  48. 12
  49. 13
  50. 14
  51. 15
  52. 16
  53. 17
  54. 18

(3) FutureData.java

  1. public class FutureData implements Data {
  2. protected RealData realdata = null;
  3. protected boolean isReady = false;
  4. public synchronized void setRealData(RealData realdata) {
  5. if (isReady) {
  6. return;
  7. }
  8. this.realdata = realdata;
  9. isReady = true;
  10. notifyAll();
  11. }
  12. public synchronized String getResult() {
  13. while (!isReady) {
  14. try {
  15. wait();
  16. } catch (InterruptedException e) {
  17. }
  18. }
  19. return realdata.result;
  20. }
  21. }
  22. 1
  23. 2
  24. 3
  25. 4
  26. 5
  27. 6
  28. 7
  29. 8
  30. 9
  31. 10
  32. 11
  33. 12
  34. 13
  35. 14
  36. 15
  37. 16
  38. 17
  39. 18
  40. 19
  41. 20
  42. 21
  43. 1
  44. 2
  45. 3
  46. 4
  47. 5
  48. 6
  49. 7
  50. 8
  51. 9
  52. 10
  53. 11
  54. 12
  55. 13
  56. 14
  57. 15
  58. 16
  59. 17
  60. 18
  61. 19
  62. 20
  63. 21

(4) Client.java

  1. public class Client {
  2. public Data request(final String queryStr) {
  3. final FutureData future = new FutureData();
  4. // RealData的构建很慢
  5. new Thread() {
  6. public void run() {
  7. RealData realdata = new RealData(queryStr);
  8. future.setRealData(realdata);
  9. }
  10. }.start();
  11. return future;
  12. }
  13. }
  14. 1
  15. 2
  16. 3
  17. 4
  18. 5
  19. 6
  20. 7
  21. 8
  22. 9
  23. 10
  24. 11
  25. 12
  26. 13
  27. 1
  28. 2
  29. 3
  30. 4
  31. 5
  32. 6
  33. 7
  34. 8
  35. 9
  36. 10
  37. 11
  38. 12
  39. 13

(5) Main.java

  1. public class Main {
  2. public static void main(String[] args) {
  3. Client client = new Client();
  4. Data data = client.request("a");
  5. System.out.println("请求完毕");
  6. try {
  7. //这里可以用一个sleep代替了对其它业务逻辑的处理
  8. Thread.sleep(2000);
  9. } catch (InterruptedException e) {
  10. }
  11. //使用真实的数据
  12. System.out.println("数据 = " + data.getResult());
  13. }
  14. }
  15. 1
  16. 2
  17. 3
  18. 4
  19. 5
  20. 6
  21. 7
  22. 8
  23. 9
  24. 10
  25. 11
  26. 12
  27. 13
  28. 14
  29. 15
  30. 1
  31. 2
  32. 3
  33. 4
  34. 5
  35. 6
  36. 7
  37. 8
  38. 9
  39. 10
  40. 11
  41. 12
  42. 13
  43. 14
  44. 15

输出结果:
请求完毕
数据 = aaaaaaaaaa

future jdk实现

futurejdk.png

(1) RealData.java

  1. import java.util.concurrent.Callable;
  2. public class RealData implements Callable<String> {
  3. private String para;
  4. public RealData(String para){
  5. this.para=para;
  6. }
  7. @Override
  8. public String call() throws Exception {
  9. StringBuffer sb=new StringBuffer();
  10. for (int i = 0; i < 10; i++) {
  11. sb.append(para);
  12. try {
  13. Thread.sleep(100);
  14. } catch (InterruptedException e) {
  15. }
  16. }
  17. return sb.toString();
  18. }
  19. }
  20. 1
  21. 2
  22. 3
  23. 4
  24. 5
  25. 6
  26. 7
  27. 8
  28. 9
  29. 10
  30. 11
  31. 12
  32. 13
  33. 14
  34. 15
  35. 16
  36. 17
  37. 18
  38. 19
  39. 20
  40. 21
  41. 22
  42. 1
  43. 2
  44. 3
  45. 4
  46. 5
  47. 6
  48. 7
  49. 8
  50. 9
  51. 10
  52. 11
  53. 12
  54. 13
  55. 14
  56. 15
  57. 16
  58. 17
  59. 18
  60. 19
  61. 20
  62. 21
  63. 22

(2) Main.java

  1. import java.util.concurrent.ExecutionException;
  2. import java.util.concurrent.ExecutorService;
  3. import java.util.concurrent.Executors;
  4. import java.util.concurrent.FutureTask;
  5. public class Main {
  6. public static void main(String[] args) throws InterruptedException, ExecutionException {
  7. //构造FutureTask
  8. FutureTask<String> future = new FutureTask<String>(new RealData("a"));
  9. ExecutorService executor = Executors.newFixedThreadPool(1);
  10. //执行FutureTask,相当于上例中的 client.request("a") 发送请求
  11. //在这里开启线程进行RealData的call()执行
  12. executor.submit(future);
  13. System.out.println("请求完毕");
  14. try {
  15. //这里依然可以做额外的数据操作,这里使用sleep代替其他业务逻辑的处理
  16. Thread.sleep(2000);
  17. } catch (InterruptedException e) {
  18. }
  19. //相当于上例中得data.getContent(),取得call()方法的返回值
  20. //如果此时call()方法没有执行完成,则依然会等待
  21. System.out.println("数据 = " + future.get());
  22. }
  23. }
  24. 1
  25. 2
  26. 3
  27. 4
  28. 5
  29. 6
  30. 7
  31. 8
  32. 9
  33. 10
  34. 11
  35. 12
  36. 13
  37. 14
  38. 15
  39. 16
  40. 17
  41. 18
  42. 19
  43. 20
  44. 21
  45. 22
  46. 23
  47. 24
  48. 1
  49. 2
  50. 3
  51. 4
  52. 5
  53. 6
  54. 7
  55. 8
  56. 9
  57. 10
  58. 11
  59. 12
  60. 13
  61. 14
  62. 15
  63. 16
  64. 17
  65. 18
  66. 19
  67. 20
  68. 21
  69. 22
  70. 23
  71. 24

输出结果:
请求完毕
数据 = aaaaaaaaaa

发表评论

表情:
评论列表 (有 0 条评论,193人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Java发包

    Java线程:新特征-线程池 Sun在Java5中,对Java线程的类库做了大量的扩展,其中线程池就是Java5的新特征之一,除了线程池之外,还有很多多线程相关的内容,为多线