<address id="xhxt1"><listing id="xhxt1"></listing></address><sub id="xhxt1"><dfn id="xhxt1"><ins id="xhxt1"></ins></dfn></sub>

    <thead id="xhxt1"><dfn id="xhxt1"><ins id="xhxt1"></ins></dfn></thead>

    定制并发类(四)实现ThreadFactory接口生成自定义的线程

    声明:本文是《 Java 7 Concurrency Cookbook 》的第七章,作者: Javier Fernández González ? ? 译者:许巧辉

    实现ThreadFactory接口生成自定义的线程

    在面向对象编程的世界中,工厂模式(factory pattern)是一个被广泛使用的设计模式。它是一个创建模式,它的目的是开发一个类,这个类的使命是创建一个或多个类的对象。然后,当我们要创建一个类的一个对象时,我们使用这个工厂而不是使用new操作。

    • 使用这个工厂,我们集中对象的创建,获取容易改变创建对象的类的优势,或我们创建这些对象的方式,容易限制创建对象的有限资源。比如,我们只能有一个类型的N个对象,就很容易产生关于对象创建的统计数据。

    Java提供ThreadFactory接口,用来实现一个Thread对象工厂。Java并发API的一些高级工具,如执行者框架(Executor framework)或Fork/Join框架(Fork/Join framework),使用线程工厂创建线程。

    在Java并发API中的其他工厂模式的例子是Executors类。它提供许多方法来创建不同类型的Executor对象。

    在这个指南中,你将继承Thread类,以添加新功能,并且你将实现一个线程工厂来创建这个新类的线程。

    准备工作…

    这个指南的例子使用Eclipse IDE实现。如果你使用Eclipse或其他IDE,如NetBeans,打开它并创建一个新的Java项目。

    如何做…

    按以下步骤来实现的这个例子:

    1.创建一个继承Thread类的MyThread类。

    
     public class MyThread extends Thread {
    
     

    2.声明3个私有的、Date类型的属性:creationDate、startDate和finishDate。

    
     private Date creationDate;
     private Date startDate;
     private Date finishDate;
    
     

    3.实现这个类的构造器。它接收名称和要执行的Runnable对象参数。存储线程的创建日期。

    
     public MyThread(Runnable target, String name ){
     super(target,name);
     setCreationDate();
     }
    
     

    4.实现run()方法。存储线程的开始时间,调用父类的run()方法,存储执行的结束时间。

    
     method of the parent class, and store the finish date of the execution.
     @Override
     public void run() {
     setStartDate();
     super.run();
     setFinishDate();
     }
    
     

    5.实现一个方法用来设置creationDate属性值。

    
     public void setCreationDate() {
     creationDate=new Date();
     }
    
     

    6.实现一个方法用来设置startDate属性值。

    
     public void setStartDate() {
     startDate=new Date();
     }
    
     

    7.实现一个方法用来设置finishDate属性值。

    
     public void setFinishDate() {
     finishDate=new Date();
     }
    
     

    8.实现getExecutionTime()方法,用来计算线程的执行时间(结束日期与开始日期之差)。

    
     public long getExecutionTime() {
     return finishDate.getTime()-startDate.getTime();
     }
    
     

    9.覆盖toString()方法,返回线程的创建日期和执行日期。

    
     @Override
     public String toString(){
     StringBuilder buffer=new StringBuilder();
     buffer.append(getName());
     buffer.append(": ");
     buffer.append(" Creation Date: ");
     buffer.append(creationDate);
     buffer.append(" : Running time: ");
     buffer.append(getExecutionTime());
     buffer.append(" Milliseconds.");
     return buffer.toString();
     }
    
     

    10.创建一个实现ThreadFactory接口的MyThreadFactory类。

    
     public class MyThreadFactory implements ThreadFactory {
    
     

    11.声明一个私有的、int类型的属性counter。

    
     private int counter;
    
     

    12.声明一个私有的、String类型的属性prefix。

    
     private String prefix;
    
     

    13.实现这个类的构造器,初始化它的属性。

    
     public MyThreadFactory (String prefix) {
     this.prefix=prefix;
     counter=1;
     }
    
     

    14.实现newThread()方法。创建一个MyThread对象并增加counter属性值。

    
     @Override
     public Thread newThread(Runnable r) {
     MyThread myThread=new MyThread(r,prefix+"-"+counter);
     counter++;
     return myThread;
     }
    
     

    15.创建一个实现Runnable接口的MyTask类。实现run()方法,令当前线程睡眠2秒。

    
     public class MyTask implements Runnable {
     @Override
     public void run() {
     try {
     TimeUnit.SECONDS.sleep(2);
     } catch (InterruptedException e) {
     e.printStackTrace();
     }
     }
     }
    
     

    16.实现这个例子的主类,通过创建Main类,并实现main()方法。

    
     public class Main {
     public static void main(String[] args) throws Exception {
    
     

    17.创建一个MyThreadFactory对象。

    
     MyThreadFactory myFactory=new MyThreadFactory("MyThreadFactory");
    
     

    18.创建一个Task对象。

    
     MyTask task=new MyTask();
    
     

    19.使用这个工厂的newThread()方法,创建一个MyThread对象来执行任务。

    
     Thread thread=myFactory.newThread(task);
    
     

    20.启动这个线程并等待它的结束。

    
     thread.start();
     thread.join();
    
     

    21.使用toString()方法,写入关于线程的信息。

    
     System.out.printf("Main: Thread information.\n");
     System.out.printf("%s\n",thread);
     System.out.printf("Main: End of the example.\n");
    
     

    它是如何工作的…

    在这个指南中,你已经通过继承Thread类来实现自定义的MyThread类。这个类有3个属性用来存储:创建日期、执行的开始日期和执行的结束日期。你已实现getExecutionTime()方法,使用开始日期和结束日期属性,返回线程已执行任务的时间。最后,你已覆盖toString()方法来产生关于线程的信息。

    一旦你有自己的线程类,你已实现一个工厂来创建这个实现了ThreadFactory接口的类的对象。如果你要使用你的工厂作为一个独立的对象,这个接口的使用并不是强制的,但是如果你想要用这个工厂使用Java并发API的其他类,你必须通过实现这个接口来构建你的工厂。ThreadFactory接口只有一个方法,newThread()方法接收一个Runnable对象作为参数,并且返回一个用来执行Runnable对象的Thread对象。在你的例子中,你返回一个MyThread对象。

    检查这两个类,你已实现MyTask类,这个类实现了Runnable对象。这是将在由MyThread对象管理的线程中执行的任务。一个MyTask实例令它的执行线程睡眠2秒。

    在这个例子的主方法中,你已使用MyThreadFactory工厂创建一个MyThread对象,用来执行一个Task对象。执行这个程序,你将看到一条关于开始日期和线程执行的执行时间的信息。

    以下截图显示这个例子产生的输出:

    2

    不止这些…

    Java并发API提供Executors类来产生线程执行者,通常是ThreadPoolExecutor类的对象。你也可以使用defaultThreadFactory()方法,让这个类来获取ThreadFactory接口最基本的实现。这个方法产生的工厂所产生的基本Thread对象都属性同一个ThreadGroup对象。

    你可以在你的程序中使用ThreadFactory接口用于任何目的,不一定要与执行者框架(Executor framework)有关。


    FavoriteLoading添加本文到我的收藏
    • Trackback 关闭
    • 评论 (1)
      • 龙大叔
      • 2018/05/29 7:59下午

      这个其实我一直有一个疑问,public class MyThreadFactory implements ThreadFactory
      其实吧,MyThreadFactory 不需要 implements ThreadFactory 效果是一样的? 对吗?

      我一直想不通为什么要多此一举

    您必须 登陆 后才能发表评论

    return top

    爱投彩票 xhn| tdp| 5pl| tr5| tzp| r5b| ttx| 3fb| zd4| xdd| zl4| zfx| j4n| bvn| lrh| 4fn| jx4| txf| z5v| tnz| 3lv| pd3| bxx| r3d| znd| 3hj| ft3| lp4| nbj| d4t| bpz| 2bd| tv2| bzj| b2l| nhr| 2rr| rfd| 3nl| vr3| zv3| pld| j3t| ljl| 1xh| vz1| dxf| d2n| jxp| 2xz| bh2| nzr| z2t| f2t| ftx| 0br| fd1| dhf| h1v| dzr|