用ThreadLocal管理线程,Callable<V>接口实现有返回值的线程

ThreadLocal在我的笔记"关于线程同步"的第5种方式里面有介绍,这里就不多说了。

--如果朋友您想转载本文章请注明转载地址"http://www.cnblogs.com/XHJT/p/3899890.html  "谢谢--

Callable<V>接口类似于Runnable,两者都是为了哪些其实例可能被另一个线程执行的类设计的,
但是Runnable不会返回结果,并且无法抛出异常。
在实现此接口的时候,需要重写call()方法:
    V call() throws Exception
   
在本次实例代码中还用到Future<V>接口
    Future<V>接口表示异步计算的结果。它提供了检查计算是否完成的方法,以等待计算的完成,
    并获取计算的结果。计算完成后只能使用get()方法来获取结果,如有必要计算完成前可以阻塞此方法。
    取消则由cancel方法来执行。
    实现此接口需要重写get()方法:
        V  get() throws InterruptedException,ExecutionException
       
代码实例:
    还是线程同步里面的那个存钱的例子,在这里实现异步计算和线程返回值

  1. package com.xhj.thread;
  2.  
  3. import java.util.concurrent.Callable;
  4. import java.util.concurrent.FutureTask;
  5.  
  6. /**
  7. * Runnable接口实现的线程是没有返回值,本实例将运用Callable<V>接口实现一个有返回值的线程应用
  8. *
  9. * @author XIEHEJUN
  10. *
  11. */
  12. public class ReturnValuesToThread {
  13. private int a = 1;
  14.  
  15. class Bank {
  16.  
  17. private int account = 100;
  18.  
  19. public int getAccount() {
  20. return account;
  21. }
  22.  
  23. /**
  24. * 存钱
  25. *
  26. * @param money
  27. */
  28. public void save(int money) {
  29. account += money;
  30. }
  31.  
  32. }
  33.  
  34. private class Transfer implements Callable<Integer> {
  35. private Bank bank;
  36.  
  37. public Transfer(Bank bank) {
  38. this.bank = bank;
  39.  
  40. }
  41.  
  42. /**
  43. * 重写call()方法,并执行一个线程
  44. */
  45. @Override
  46. public Integer call() throws Exception {
  47. int flag = a++;
  48. System.out.println("启动线程" + flag);
  49. for (int i = 0; i < 10; i++) {
  50. bank.save(10);
  51. System.out.println("账户的余额为:" + bank.getAccount());
  52. }
  53. return bank.getAccount();
  54. }
  55. }
  56.  
  57. /**
  58. * 建立线程,调用内部类,开始存钱
  59. */
  60. public void useThread() {
  61. /*
  62. * 这里属于异步操作,故要建立两个Bank对象,倘若只建立一个对象则是对同一个资源进行同步操作,
  63. * 那么第二线程将会在第一个线程操作完,并释放资源之后才会执行,
  64. * 但是此时第二个线程得到的本金将不再是最开始初始化的本金而是第一个线程完成操作之后返回的值,而最后的实际金额就是第二个线程的计算结果
  65. */
  66. Bank bank1 = new Bank();
  67. Bank bank2 = new Bank();
  68. Transfer transfer1 = new Transfer(bank1);
  69. Transfer transfer2 = new Transfer(bank2);
  70. FutureTask<Integer> task1 = new FutureTask<Integer>(transfer1);
  71. FutureTask<Integer> task2 = new FutureTask<Integer>(transfer2);
  72. Thread thread1 = new Thread(task1);
  73. Thread thread2 = new Thread(task2);
  74. thread1.start();
  75. thread2.start();
  76. try {
  77. int threadResult1 = task1.get();
  78. int threadResult2 = task2.get();
  79. System.out.println("一号线程的计算结果是 --" + threadResult1);
  80. System.out.println("二号线程的计算结果是 --" + threadResult2);
  81. int sum = threadResult1 + threadResult2;
  82. int count = sum - 100;
  83. System.out.println("实际金额是 --" + count
  84. + " (一号线程的计算结果加上二号线程的计算结果再减去100的本金)");
  85. } catch (Exception e) {
  86. System.out.println(e.getMessage());
  87. }
  88. }
  89.  
  90. public static void main(String[] args) {
  91. ReturnValuesToThread rethread = new ReturnValuesToThread();
  92. rethread.useThread();
  93.  
  94. }
  95.  
  96. }

注:在处理有返回值的线程的时候,要记得捕获异常

java笔记--用ThreadLocal管理线程,Callable<V>接口实现有返回值的线程的更多相关文章

  1. Java面向对象(Eclipse高级、类与接口作为参数返回值)

      面向对象 今日内容介绍 u Eclipse常用快捷键操作 u Eclipse文档注释导出帮助文档 u Eclipse项目的jar包导出与使用jar包 u 不同修饰符混合使用细节 u 辨析何时定义变 ...

  2. Java线程:线程安全类和Callable与Future(有返回值的线程)

    一.线程安全类 当一个类已经很好的同步以保护它的数据时,这个类就称为线程安全的.当一个集合是安全的,有两个线程在操作同一个集合对象,当第一个线程查询集合非空后,删除集合中所有元素的时候,第二个线程也来 ...

  3. Callable接口--有返回值的线程

    Callable java5之前是没有返回值的,Java5新增了Callable接口获得线程的返回值,可返回值的任务必须实现Callable接口,类似的,无返回值的任务必须Runnable接口.Cal ...

  4. Java线程:新特征-有返回值的线程

    http://lavasoft.blog.51cto.com/62575/222082/ Java线程:新特征-有返回值的线程 2009-11-04 17:33:56 标签:返回值 职场 线程 休闲 ...

  5. Java中使用有返回值的线程

    在创建多线程程序的时候,我们常实现Runnable接口,Runnable没有返回值,要想获得返回值,Java5提供了一个新的接口Callable,可以获取线程中的返回值,但是获取线程的返回值的时候,需 ...

  6. Java线程:新特征-有返回值的线程《转》

      原始文章   在Java5之前,线程是没有返回值的,常常为了“有”返回值,破费周折,而且代码很不好写.或者干脆绕过这道坎,走别的路了.   现在Java终于有可返回值的任务(也可以叫做线程)了. ...

  7. 工作随笔——Java调用Groovy类的方法、传递参数和获取返回值

    接触Groovy也快一年了,一直在尝试怎么将Groovy引用到日常工作中来.最近在做一个功能的时候,花了点时间重新看了下Java怎么调用Groovy的方法.传递参数和获取返回值. 示例Groovy代码 ...

  8. Java线程中带有返回值的线程Callable

    在Java5之前,线程是没有返回值的,常常为了“有”返回值,破费周折,而且代码很不好写.或者干脆绕过这道坎,走别的路了.现在Java终于有可返回值的任务(也可以叫做线程)了. 可返回值的任务必须实现C ...

  9. Java Callable接口——有返回值的线程

    实际开发过程中,我们常常需要等待一批线程都返回结果后,才能继续执行.<线程等待——CountDownLatch使用>中我们介绍了CountDownLatch的使用,通过使用CountDow ...

随机推荐

  1. JS的解析机制

    JS的解析机制,是JS的又一大重点知识点,在面试题中更经常出现,今天就来唠唠他们的原理.首先呢,我们在我们伟大的浏览器中,有个叫做JS解析器的东西,它专门用来读取JS,执行JS.一般情况是存在作用域就 ...

  2. WPF开发时光之痕日记本(二)—— MVVM基类

    当我们用MVVM的时候要实现INotifyPropertyChanged,每次都要实现这个接口比较麻烦,所以基类的作用就体现出来了.代码如下: public class ViewModelBase : ...

  3. 记”Uri.IsWellFormedUriString”中的BUG

    场景 先上逻辑代码 1: /// <summary> 2: /// 图片真实地址 3: /// </summary> 4: public string FullImagePat ...

  4. Python2和Python3 爬虫 转换

    由于Python3的不断完善,很多新入Python的小伙伴选择了Python3的阵营,很多人选择了爬虫这一热门话题,但是网络上大部分教程都是Python2 教程,Python3这一块做了些许的改动,对 ...

  5. 让Dapper+SqlCE支持ntext数据类型和超过4000字符的存储

    使用Dapper和SqlCE进行开发的时候,如果数据库的某字段是采用的ntext数据类型,并且在这个字段存储的数据超过了4000个字符,会报如下的错误: Invalid parameter Size ...

  6. 游戏服务器端引擎--DogSE的设计

    就DogSE的设计目标来说,它定位为千人左右的页游服务器,在不修改任何底层模块的情况下可以快速的写各种游戏业务.就算是新人在熟悉2~3天后也可以开始写一个游戏. 项目可以从github获得,访问地址: ...

  7. [bzoj1296][SCOI2009]粉刷匠(泛化背包)

    http://www.lydsy.com:808/JudgeOnline/problem.php?id=1296 分析: 首先预处理出每一行的g[0..T]表示这一行刷0..T次,最多得到的正确格子数 ...

  8. 编写高质量代码改善C#程序的157个建议[避免finaly内的无效代码、避免嵌套异常、避免吃掉异常、注意循环异常处理]

    前言 本文已同步到http://www.cnblogs.com/aehyok/p/3624579.html.本文主要来学习以下几点建议 建议61.避免在finally内撰写无效代码 建议62.避免嵌套 ...

  9. PHP中文处理 中文字符串截取(mb_substr)和获取中文字符串字数

    一.中文截取:mb_substr() mb_substr( $str, $start, $length, $encoding ) $str,需要截断的字符串 $start,截断开始处,起始处为0 $l ...

  10. 50个提高PHP编程效率的方法

      用单引号代替双引号来包含字符串,这样做会更快一些.因为PHP会在双引号包围的字符串中搜寻变量,单引号则不会,注意:只有echo能这么做,它是一种可以把多个字符串当作参数的“函数”(译注:PHP手册 ...