查看: 1029|回复: 1

[Java项目交流] Java中的Runnable、Callable、Future、FutureTask的区别与示例

[复制链接]
  • TA的每日心情
    无聊
    2017-4-17 15:52
  • 签到天数: 107 天

    连续签到: 1 天

    [LV.6]常住居民II

    发表于 2015-6-11 15:47:37 | 显示全部楼层 |阅读模式
    Java中存在Runnable、Callable、Future、FutureTask这几个与线程相关的类或者接口,
    在Java中也是比较重要的几个概念,我们通过下面的简单示例来了解一下它们的作用于区别。
    1. package com.effective.java.concurrent.task;

    2. import java.util.concurrent.Callable;
    3. import java.util.concurrent.ExecutionException;
    4. import java.util.concurrent.ExecutorService;
    5. import java.util.concurrent.Executors;
    6. import java.util.concurrent.Future;
    7. import java.util.concurrent.FutureTask;

    8. /**
    9. *
    10. * @author mrsimple
    11. *
    12. */
    13. public class RunnableFutureTask {

    14. /**
    15. * ExecutorService
    16. */
    17. static ExecutorService mExecutor = Executors.newSingleThreadExecutor();

    18. /**
    19. *
    20. * @param args
    21. */
    22. public static void main(String[] args) {
    23. runnableDemo();
    24. futureDemo();
    25. }

    26. /**
    27. * runnable, 无返回值
    28. */
    29. static void runnableDemo() {

    30. new Thread(new Runnable() {

    31. @Override
    32. public void run() {
    33. System.out.println("runnable demo : " + fibc(20));
    34. }
    35. }).start();
    36. }

    37. /**
    38. * 其中Runnable实现的是void run()方法,无返回值;Callable实现的是 V
    39. * call()方法,并且可以返回执行结果。其中Runnable可以提交给Thread来包装下
    40. * ,直接启动一个线程来执行,而Callable则一般都是提交给ExecuteService来执行。
    41. */
    42. static void futureDemo() {
    43. try {
    44. /**
    45. * 提交runnable则没有返回值, future没有数据
    46. */
    47. Future<?> result = mExecutor.submit(new Runnable() {

    48. @Override
    49. public void run() {
    50. fibc(20);
    51. }
    52. });

    53. System.out.println("future result from runnable : " + result.get());

    54. /**
    55. * 提交Callable, 有返回值, future中能够获取返回值
    56. */
    57. Future<Integer> result2 = mExecutor.submit(new Callable<Integer>() {
    58. @Override
    59. public Integer call() throws Exception {
    60. return fibc(20);
    61. }
    62. });

    63. System.out
    64. .println("future result from callable : " + result2.get());

    65. /**
    66. * FutureTask则是一个RunnableFuture<V>,即实现了Runnbale又实现了Futrue<V>这两个接口,
    67. * 另外它还可以包装Runnable(实际上会转换为Callable)和Callable
    68. * <V>,所以一般来讲是一个符合体了,它可以通过Thread包装来直接执行,也可以提交给ExecuteService来执行
    69. * ,并且还可以通过v get()返回执行结果,在线程体没有执行完成的时候,主线程一直阻塞等待,执行完则直接返回结果。
    70. */
    71. FutureTask<Integer> futureTask = new FutureTask<Integer>(
    72. new Callable<Integer>() {
    73. @Override
    74. public Integer call() throws Exception {
    75. return fibc(20);
    76. }
    77. });
    78. // 提交futureTask
    79. mExecutor.submit(futureTask) ;
    80. System.out.println("future result from futureTask : "
    81. + futureTask.get());

    82. } catch (InterruptedException e) {
    83. e.printStackTrace();
    84. } catch (ExecutionException e) {
    85. e.printStackTrace();
    86. }
    87. }

    88. /**
    89. * 效率底下的斐波那契数列, 耗时的操作
    90. *
    91. * @param num
    92. * @return
    93. */
    94. static int fibc(int num) {
    95. if (num == 0) {
    96. return 0;
    97. }
    98. if (num == 1) {
    99. return 1;
    100. }
    101. return fibc(num - 1) + fibc(num - 2);
    102. }

    103. }
    复制代码
  • TA的每日心情
    无聊
    2016-12-1 15:20
  • 签到天数: 668 天

    连续签到: 3 天

    [LV.9]以坛为家II

    发表于 2015-11-7 21:23:26 | 显示全部楼层
    线程的第三种方式
    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    站长推荐上一条 /1 下一条