前面已经指出通过实现Runnable时,Thread类的作用就是将run()方法包装成线程执行体,那么是否可以直接把任意方法都包装成线程执行体呢?Java目前不行,但其模仿者C#中是可以的.

Callabel接口可以看成是Runnable接口的增强版,只不过其线程执行体call()方法比run方法更加强大罢了:

>>call()方法中可以有返回值

>>call()方法中可以声明抛出异常.

一.创建线程的第三种方式----使用Callable对象进行创建

  1. package com.amos.concurrent;
  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. /**
  8. * @ClassName: CallableAndFuture
  9. * @Description: 多线程中的Callable和Future学习
  10. * @author: amosli
  11. * @email:hi_amos@outlook.com
  12. * @date Apr 22, 2014 12:07:26 AM
  13. */
  14. public class CallableAndFuture {
  15. public static void main(String[] args) throws Exception, ExecutionException {
  16. ExecutorService newSingleThreadExecutor = Executors.newSingleThreadExecutor();
  17. Future<String> future = newSingleThreadExecutor.submit(new Callable<String>() {
  18. public String call() throws Exception {
  19. Thread.sleep(20);
  20. return "hi,amos";
  21. }
  22. });
  23. // System.out.println("future:"+future.get(1,TimeUnit.MILLISECONDS));//等待指定的时间
  24. System.out.println("future:" + future.get());
  25. }
  26. }

效果如下:

注:

1.这里要注意的是,创建线程时执行任务不是用execute()方法去执行了,而是用submit()方法.

2.同时要注意,这里call()方法返回值,要和上面的保持一致.

3.另外,可以设置最大等待时间,就是等待程序的返回值,这里使用get()方法.

4.其常用的其它方法有cancel(),isCancelled(),isDone(),分别表示取消关联的任务,是否已经取消,任务是否已经完成.

二.CompeltionService

CompeltionService主要用于提交一组Callable对象,其take方法用于返回已完成的callable任务的Future对象.可以用麦子收割来作比喻,种了10亩地的麦子,哪一块先成熟先收割哪一块.

举例:

  1. package com.amos.concurrent;
  2.  
  3. import java.util.Random;
  4. import java.util.concurrent.Callable;
  5. import java.util.concurrent.CompletionService;
  6. import java.util.concurrent.ExecutionException;
  7. import java.util.concurrent.ExecutorCompletionService;
  8. import java.util.concurrent.ExecutorService;
  9. import java.util.concurrent.Executors;
  10. public class CallableAndFuture {
  11.  
  12. public static void main(String[] args) throws Exception, ExecutionException {
  13. ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(10);
  14. CompletionService<Integer> completionService = new ExecutorCompletionService<Integer>(newFixedThreadPool);
  15. for(int i=0;i<11;i++){//创建10个任务
  16. final int task=i;
  17. completionService.submit(new Callable<Integer>() {//提交任务
  18. public Integer call() throws Exception {
  19. Thread.sleep(new Random().nextInt(3000));//最多3秒
  20. return task;
  21. }
  22. });
  23. }
  24. //take
  25. for(int i=0;i<11;i++){
  26. System.out.println("已完成的任务:"+completionService.take().get());
  27. }
  28. }

效果如下图所示:

注:由结果也可以看出来,其随机结果是根据任务的先后完成顺序来的,使用其take()方法可以获取其返回结果.

java核心知识点学习----创建线程的第三种方式Callable和Future CompletionService的更多相关文章

  1. java核心知识点----创建线程的第三种方式 Callable 和 Future CompletionService

    前面已经指出通过实现Runnable时,Thread类的作用就是将run()方法包装成线程执行体,那么是否可以直接把任意方法都包装成线程执行体呢?Java目前不行,但其模仿者C#中是可以的. Call ...

  2. Java反射机制(创建Class对象的三种方式)

    1:了解什么是反射机制? 在通常情况下,如果有一个类,可以通过类创建对象:但是反射就是要求通过一个对象找到一个类的名称:   2:在反射操作中,握住一个核心概念: 一切操作都将使用Object完成,类 ...

  3. 创建线程的第三种方式——使用Callable接口

    Callable是类似于Runnable的接口,实现Callable的类和实现Runnable的类都是可被其他线程执行的任务. 优点:有返回值 缺点:实现繁琐 简单实现: CallableAndFut ...

  4. Java核心知识点学习----线程中如何创建锁和使用锁 Lock,设计一个缓存系统

    理论知识很枯燥,但这些都是基本功,学完可能会忘,但等用的时候,会发觉之前的学习是非常有意义的,学习线程就是这样子的. 1.如何创建锁? Lock lock = new ReentrantLock(); ...

  5. java核心知识点学习----并发和并行的区别,进程和线程的区别,如何创建线程和线程的四种状态,什么是线程计时器

    多线程并发就像是内功,框架都像是外功,内功不足,外功也难得精要. 1.进程和线程的区别 一个程序至少有一个进程,一个进程至少有一个线程. 用工厂来比喻就是,一个工厂可以生产不同种类的产品,操作系统就是 ...

  6. Java核心知识点学习----使用Condition控制线程通信

    一.需求 实现线程间的通信,主线程循环3次后,子线程2循环2次,子线程3循环3次,然后主线程接着循环3次,如此循环3次. 即:A->B->C---A->B->C---A-> ...

  7. Java核心知识点学习----多线程中的阻塞队列,ArrayBlockingQueue介绍

    1.什么是阻塞队列? 所谓队列,遵循的是先进先出原则(FIFO),阻塞队列,即是数据共享时,A在写数据时,B想读同一数据,那么就将发生阻塞了. 看一下线程的四种状态,首先是新创建一个线程,然后,通过s ...

  8. java 中创建线程有哪几种方式?

    Java中创建线程主要有三种方式: 一.继承Thread类创建线程类 (1)定义Thread类的子类,并重写该类的run方法,该run方法的方法体就代表了线程要完成的任务.因此把run()方法称为执行 ...

  9. Java反射机制(创建Class对象的三种方式)

    1:SUN提供的反射机制的类: java.lang.Class<T> java.lang.reflect.Constructor<T> java.lang.reflect.Fi ...

随机推荐

  1. 【ASP.net】Equals 和 == 的区别

    在比较Equals 和 ==的区别前.我们先来了解下相关的知识 C#数据类型 1.值类型 值类型有: 值类型包括:简单类型.结构类型.枚举类型:引用类型包括:Object 类型.类类型.接口.代表元. ...

  2. android学习笔记53——自动朗读TTS

    自动朗读TTS android提供了自动朗读功能--其指的是支持可以对指定文本内容进行朗读,从而发出声音: 同时android的自动朗读支持还允许把文本对应的音频录制成音频文件,方便后续播放. 这种自 ...

  3. H5课程大纲

    K1模块课程: 课程模块 课程阶段 课程内容 K1 模块 第1阶段 认识前端开发 环境配置.使用标签的分类.写法及使用规范CSS样式的使用.各类常见样式Photoshop使用16大常用样式盒模型.语义 ...

  4. Visual Studio 2015里面汇编工具Asm Dude的配置!

    最近开始学习汇编,也开始使用Visual Studio 2015写汇编程序,比较了半天,最后觉得Asm Dude应该是目前Visual Studio 2015非常好的汇编开发插件了,但是如果默认安装上 ...

  5. WPF绑定数据源

    using System;using System.Collections.Generic;using System.Collections.ObjectModel;using System.Comp ...

  6. PHP使用feof()函数读文件的方法

    这篇文章主要介绍了PHP使用feof()函数读文件的方法,以实例形式对比了正确与错误的用法,阐明了feof()函数的使用技巧,需要的朋友可以参考下 本文实例讲述了PHP使用feof()函数读文件的方法 ...

  7. IIS7 rename application or site

    rename site 比较容易,在IIS里面就可以直接 rename,也可以用 cmd 的方式 1. 打开 cmd 2. cd C:\Windows\System32\inetsrv 3. appc ...

  8. 关于sublime text2

    转自:http://www.qianduan.net/essential-to-sublime-the-text-2-plugins.html Sublime Text 2是一个轻量.简洁.高效.跨平 ...

  9. VS2010+VMWare8+VisualDDK1.5.6 创建并调试你的第一个驱动程序 - 完全教程

    本文描述了如何使用Visual Studio+VMMare+VisualDDK来创建.编译和调试你的第一个驱动程序.本文提供在开发和调试工具的环境下详细的操作步骤,而无需太多的关心这些环境背后所做的事 ...

  10. C++——CString用法大全

    列表形式的如下: CString的构造函数CString( );例:CString csStr; CString( const CString& stringSrc );例:CString c ...