`
jokermanager
  • 浏览: 140439 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

java基础--Java 5.0多线程编程(2)

阅读更多

*1: 定义了几个任务

*2: 初始了任务执行工具。任务的执行框架将会在后面解释。

*3: 执行任务,任务启动时返回了一个 Future 对象,如果想得到任务执行的结果或者是异常可对这个 Future 对象进行操作。 Future 所含的值必须跟 Callable 所含的值对映,比如说例子中 Future 对印 Callable

*4: 任务 1 正常执行完毕, future1.get() 会返回线程的值

*5: 任务 2 在进行一个死循环,调用 future2.cancel(true) 来中止此线程。传入的参数标明是否可打断线程, true 表明可以打断。

*6: 任务 3 抛出异常,调用 future3.get() 时会引起异常的抛出。

  运行 Executor 会有以下运行结果:

looping....

Task done. //*1

looping....

looping....//*2

looping....

looping....

looping....

looping....

Thread 2 terminated? :true //*3

//*4

java.util.concurrent.ExecutionException: java.lang.Exception: Callable terminated with Exception!

        at java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:205)

        at java.util.concurrent.FutureTask.get(FutureTask.java:80)

        at concurrent.Executor.main(Executor.java:43)

        …….

*1: 任务 1 正常结束

*2: 任务 2 是个死循环,这是它的打印结果

*3: 指示任务 2 被取消

*4: 在执行 future3.get() 时得到任务 3 抛出的异常

3:新的任务执行架构

   在 Java 5.0 之前启动一个任务是通过调用 Thread 类的 start() 方法来实现的,任务的提于交和执行是同时进行的,如果你想对任务的执行进行调度或是控制同时执行的线程数量就需要额外编写代码来完成。 5.0 里提供了一个新的任务执行架构使你可以轻松地调度和控制任务的执行,并且可以建立一个类似数据库连接池的线程池来执行任务。这个架构主要有三个接口和其相应的具体类组成。这三个接口是 Executor, ExecutorService ScheduledExecutorService ,让我们先用一个图来显示它们的关系:

 

  图的左侧是接口,图的右侧是这些接口的具体类。注意 Executor 是没有直接具体实现的。

Executor 接口:

是用来执行 Runnable 任务的,它只定义一个方法:

  • execute(Runnable command) :执行 Ruannable 类型的任务

ExecutorService 接口:

ExecutorService 继承了 Executor 的方法,并提供了执行 Callable 任务和中止任务执行的服务,其定义的方法主要有:

  • submit(task) :可用来提交 Callable Runnable 任务,并返回代表此任务的 Future 对象
  • invokeAll(collection of tasks) :批处理任务集合,并返回一个代表这些任务的 Future 对象集合
  • shutdown() :在完成已提交的任务后关闭服务,不再接受新任务
  • shutdownNow() :停止所有正在执行的任务并关闭服务。
  • isTerminated() :测试是否所有任务都执行完毕了。
  • isShutdown() :测试是否该 ExecutorService 已被关闭

ScheduledExecutorService 接口

ExecutorService 的基础上, ScheduledExecutorService 提供了按时间安排执行任务的功能,它提供的方法主要有:

  • schedule(task, initDelay): 安排所提交的 Callable Runnable 任务在 initDelay 指定的时间后执行。
  • scheduleAtFixedRate() :安排所提交的 Runnable 任务按指定的间隔重复执行
  • scheduleWithFixedDelay() :安排所提交的 Runnable 任务在每次执行完后,等待 delay 所指定的时间后重复执行。

代码: ScheduleExecutorService 的例子

public class ScheduledExecutorServiceTest {

        public static void main(String[] args)

               throws InterruptedException, ExecutionException{

               //*1

                ScheduledExecutorService service = Executors.newScheduledThreadPool(2);

                //*2

                Runnable task1 = new Runnable() {

                     public void run() {

                        System.out.println("Task repeating.");

                     }

                };

                //*3

                final ScheduledFuture future1 =

                        service.scheduleAtFixedRate(task1, 0, 1, TimeUnit.SECONDS);

                //*4

                ScheduledFuture future2 = service.schedule(new Callable(){

                     public String call(){

                             future1.cancel(true);

                             return "task cancelled!";

                      }

                }, 5, TimeUnit.SECONDS);

                System.out.println(future2.get());

//*5

service.shutdown();

        }

}

   这个例子有两个任务,第一个任务每隔一秒打印一句“ Task repeating , 第二个任务在 5 秒钟后取消第一个任务。

*1: 初始化一个 ScheduledExecutorService 对象,这个对象的线程池大小为 2

*2: 用内函数的方式定义了一个 Runnable 任务。

*3: 调用所定义的 ScheduledExecutorService 对象来执行任务,任务每秒执行一次。能重复执行的任务一定是 Runnable 类型。注意我们可以用 TimeUnit 来制定时间单位,这也是 Java 5.0 里新的特征, 5.0 以前的记时单位是微秒,现在可精确到奈秒。

*4: 调用 ScheduledExecutorService 对象来执行第二个任务,第二个任务所作的就是在 5 秒钟后取消第一个任务。

*5: 关闭服务。

Executors

   虽然以上提到的接口有其实现的具体类,但为了方便 Java 5.0 建议使用 Executors 的工具类来得到 Executor 接口的具体对象,需要注意的是 Executors 是一个类,不是 Executor 的复数形式。 Executors 提供了以下一些 static 的方法:

  • callable(Runnable task): Runnable 的任务转化成 Callable 的任务
  • newSingleThreadExecutor: 产生一个 ExecutorService 对象,这个对象只有一个线程可用来执行任务,若任务多于一个,任务将按先后顺序执行。
  • newCachedThreadPool(): 产生一个 ExecutorService 对象,这个对象带有一个线程池,线程池的大小会根据需要调整,线程执行完任务后返回线程池,供执行下一次任务使用。
  • newFixedThreadPool(int poolSize) :产生一个 ExecutorService 对象,这个对象带有一个大小为 poolSize 的线程池,若任务数量大于 poolSize ,任务会被放在一个 queue 里顺序执行。
  • newSingleThreadScheduledExecutor :产生一个 ScheduledExecutorService 对象,这个对象的线程池大小为 1 ,若任务多于一个,任务将按先后顺序执行。
  • newScheduledThreadPool(int poolSize): 产生一个 ScheduledExecutorService 对象,这个对象的线程池大小为 poolSize ,若任务数量大于 poolSize ,任务会在一个 queue 里等待执行

以下是得到和使用 ExecutorService 的例子:

代码:如何调用 Executors 来获得各种服务对象

//Single Threaded ExecutorService

     ExecutorService singleThreadeService = Executors.newSingleThreadExecutor();

//Cached ExecutorService

     ExecutorService cachedService = Executors.newCachedThreadPool();

//Fixed number of ExecutorService

     ExecutorService fixedService = Executors.newFixedThreadPool(3);

//Single ScheduledExecutorService

     ScheduledExecutorService singleScheduledService =

          Executors.newSingleThreadScheduledExecutor();

//Fixed number of ScheduledExecutorService

ScheduledExecutorService fixedScheduledService =

     Executors.newScheduledThreadPool(3);

4 Lockers Condition接口

   在多线程编程里面一个重要的概念是锁定,如果一个资源是多个线程共享的,为了保证数据的完整性,在进行事务性操作时需要将共享资源锁定,这样可以保证在做事务性操作时只有一个线程能对资源进行操作,从而保证数据的完整性。在 5.0 以前,锁定的功能是由 Synchronized 关键字来实现的,这样做存在几个问题:

  • 每次只能对一个对象进行锁定。若需要锁定多个对象,编程就比较麻烦,一不小心就会出现死锁现象。
  • 如果线程因拿不到锁定而进入等待状况,是没有办法将其打断的

Java 5.0 里出现两种锁的工具可供使用,下图是这两个工具的接口及其实现:

 

 

分享到:
评论

相关推荐

    Java5.0多线程编程

    最新Java 5.0多线程编程。

    Java5.0多线程编程实践.pdf

    Java5.0多线程编程实践.pdf

    Java 5.0多线程编程

    java Java多线程 多线程 java Java多线程 多线程 java Java多线程 多线程

    Java高手真经(编程基础卷)光盘全部源码 免积分

    javathread.zip 10.Java多线程编程(线程池、生产者消费者、存取款实例) javautil.zip 11.Java常用实体类 javaxml.zip 14.XML属性文件 第4部分(6个程序包) javagui.zip 15.Java GUI库对比实例 javaawt.zip ...

    Java高手真经(编程基础卷)光盘全部源码

    javathread.zip 10.Java多线程编程(线程池、生产者消费者、存取款实例) javautil.zip 11.Java常用实体类 javaxml.zip 14.XML属性文件 第4部分(6个程序包) javagui.zip 15.Java GUI库对比实例 javaawt.zip 16....

    (超赞)JAVA精华之--深入JAVA API

    1.7 Java 5.0多线程编程 1.8 Java Socket编程 1.9 Java的内存泄漏 1.10 抽象类与接口的区别 1.11 Java变量类型间的相互转换 2 JAVA与WEB 2.1 JMX规范 2.1.1 JMX概述 2.1.2 设备层(Instrumentation Level) 2.1.3 ...

    多线程编程(电子书)

    Java自1995年面世以来得到了广泛得一个运用,但是对多...在Java 5.0之前Java里的多线程编程主要是通过Thread类,Runnable接口,Object对象中的wait()、 notify()、 notifyAll()等方法和synchronized关键词来实现的。

    精通Java:JDK、数据库系统开发Web开发(实例代码)

    《精通Java:JDK、数据库系统开发Web开发》全书共分27章,内容涵盖了Java编程环境概述、基础语法、面向对象软件设计方法、线程、数据集合、网络编程、图形编程、多媒体编程以及Java Web开发。本书每一节的例子都是...

    java学习笔记 初学者必读

    1. 前言 1-4 1.1. JAVA特点 1-4 1.2. 运行原理 1-4 1.3. JAVA目录 1-4 2. 一•基础知识 2-4 2.1. 配置环境 2-4 2.2. Java中基本概念 2...17.9. JAVA5.0 的注释 (Annotation) 17-73 17.10. Callable 和 Future接口 17-74

    JAVA2核心技术(中文的PDF).part2.rar

    全面覆盖Java 2技术的高级主题,包括:多线程、集合框架、网络API、数据库编程、分布式对象等,深入探究了Swing、Java 2D API、Javaean、Java安全模式、XML、注释、元数据等主题,同量涉及本地方法、国际化以及JDK ...

    JAVA2核心技术第7版卷2高级特性-中文版

    全面覆盖Java 2技术的高级主题,包括:多线程、集合框架、网络API、数据库编程、分布式对象等,深入探究了Swing、Java 2D API、Javaean、Java安全模式、XML、注释、元数据等主题,同量涉及本地方法、国际化以及JDK ...

    Java优化编程(第2版)

    Java优化编程(第2版)通过丰富、完整、富有代表性的实例,展示了如何提升Java应用性能,并且给出了优化前与优化后的Java应用程序的性能差别,以实际的实例与数字告诉你,为什么不可以这么做,应该怎么做,深入分析...

    Java精华学习资料

    Java精华学习资料 深入JAVA API 深入理解嵌套类和内部类 文件和流 java中的一些常用词汇 ...Java 5.0多线程编程 Java Socket编程 Java的内存泄漏 抽象类与接口的区别 Java变量类型间的相互转换 ……

    JAVA2核心技术(中文的PDF).part1.rar

    全面覆盖Java 2技术的高级主题,包括:多线程、集合框架、网络API、数据库编程、分布式对象等,深入探究了Swing、Java 2D API、Javaean、Java安全模式、XML、注释、元数据等主题,同量涉及本地方法、国际化以及JDK ...

    java高手真经 光盘源码

    javathread.zip 10.Java多线程编程(线程池、生产者消费者、存取款实例) javautil.zip 11.Java常用实体类 javaxml.zip 14.XML属性文件 第4部分(6个程序包) javagui.zip 15.Java GUI库对比实例 javaawt.zip ...

Global site tag (gtag.js) - Google Analytics