《Java程序员面试秘笈》—— 1.13 使用工厂类创建线程

简介: 工厂模式是面向对象编程中最常使用的模式之一。它是一个创建者模式,使用一个类为其他的一个或者多个类创建对象。当我们要为这些类创建对象时,不需再使用new构造器,而使用工厂类。

本节书摘来异步社区《Java 7并发编程实战手册》一书中的第1章,第1.13节,作者:【西】Javier Fernández González,更多章节内容可以访问云栖社区“异步社区”公众号查看。

1.13 使用工厂类创建线程

工厂模式是面向对象编程中最常使用的模式之一。它是一个创建者模式,使用一个类为其他的一个或者多个类创建对象。当我们要为这些类创建对象时,不需再使用new构造器,而使用工厂类。

使用工厂类,可以将对象的创建集中化,这样做有以下的好处:

◆ 更容易修改类,或者改变创建对象的方式;

◆ 更容易为有限资源限制创建对象的数目。例如,我们可以限制一个类型的对象不多于n个。

◆ 更容易为创建的对象生成统计数据。

Java提供了ThreadFactory接口,这个接口实现了线程对象工厂。Java并发API的高级工具类也使用了线程工厂创建线程。

在本节中,我们将学习如何通过实现ThreadFactory接口来创建线程对象,用以生成个性化名称的线程并且保存这些线程对象的统计信息。

准备工作
本节的范例是在Eclipse IDE里完成的。无论你使用Eclipse还是其他的IDE(比如NetBeans),都可以打开这个IDE并且创建一个新的Java工程。

范例实现
按照接下来的步骤实现本节的范例。

1.创建名为MyThreadFactory的类,并且实现ThreadFactory接口。
``
public class MyThreadFactory implements ThreadFactory {``
2.声明3个属性:整型数字counter,用来存储线程对象的数量;字符串name,用来存放每个线程的名称;字符串列表stats,用来存放线程对象的统计数据。同时实现带参数的构造器来初始化这3个属性。

private int counter;
private String name;
private List<String> stats;
public MyThreadFactory(String name){
  counter=0;
  this.name=name;
  stats=new ArrayList<String>();
}```
3.实现newThread()方法。这个方法以Runnable接口对象为参数,并且返回参数对应的线程对象。这里我们创建一个线程对象并生成线程名称,保存统计数据。

@Override
public Thread newThread(Runnable r) {
Thread t=new Thread(r,name+"-Thread_"+counter);
counter++;
stats.add(String.format("Created thread %d with name %s on %sn",t.getId(),t.getName(),new Date()));
return t;
}`
4.实现getStatistics()方法,返回一个字符串对象,用来表示所有线程对象的统计数据。

public String getStats(){
  StringBuffer buffer=new StringBuffer();
  Iterator<String> it=stats.iterator();
  while (it.hasNext()) {
    buffer.append(it.next());
    buffer.append("\n");
    }
    return buffer.toString();
}```
5.创建名为Task的类并且实现Runnable接口。在这个范例中,线程除了只休眠1秒钟之外,不做任何事情。

public class Task implements Runnable {

@Override
public void run() {
try {
    TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
  e.printStackTrace();
}

}
}`
6.创建范例的主程序。创建一个包含main()方法的主类Main。

public class Main {
  public static void main(String[] args) {```
7.创建一个MyThreadFactory对象,创建一个Task对象。

MyThreadFactory factory=new MyThreadFactory("MyThreadFactory");
Task task=new Task();`
8.使用工厂类MyThreadFactory创建10个线程对象,并且启动它们。

Thread thread;
System.out.printf("Starting the Threads\n");
for (int i=0; i<10; i++){
  thread=factory.newThread(task);
  thread.start();
}```
9.将线程工厂的统计打印到控制台。

System.out.printf("Factory stats:n");
System.out.printf("%sn",factory.getStats());`
10.运行范例并且查看运行结果。

工作原理
ThreadFactory接口只有一个方法,即newThread,它以Runnable接口对象作为传入

参数并且返回一个线程对象。当实现ThreadFactory接口时,必须实现覆盖这个方法。大多数基本的线程工厂类只有一行,即:
``
return new Thread(r);``
可以通过增加一些变化来强化实现方法覆盖。

◆ 创建一个个性化线程,如本范例使用一个特殊的格式作为线程名,或者通过继承Thread类来创建自己的线程类;

◆ 保存新创建的线程的统计数据,如本节的范例那样;

◆ 限制创建的线程的数量;

◆ 对生成的线程进行验证;

◆ 更多你可以想到的。

使用工厂设计模式是一个很好的编程实践,但是,如果是通过实现ThreadFactory接口来创建线程,你必须检查代码,以保证所有的线程都是使用这个工厂创建的。

相关文章
|
23小时前
|
自然语言处理 Java API
Java 8的Stream API和Optional类:概念与实战应用
【5月更文挑战第17天】Java 8引入了许多重要的新特性,其中Stream API和Optional类是最引人注目的两个。这些特性不仅简化了集合操作,还提供了更好的方式来处理可能为空的情况,从而提高了代码的健壮性和可读性。
22 7
|
1天前
|
安全 Java 数据库
Spring boot 入门教程-Oauth2,java面试基础题核心
Spring boot 入门教程-Oauth2,java面试基础题核心
|
1天前
|
Java
Java中int[]与Integer[]相互转化的方法,java基础知识面试重点总结
Java中int[]与Integer[]相互转化的方法,java基础知识面试重点总结
|
1天前
|
设计模式 算法 Java
Java的前景如何,好不好自学?,万字Java技术类校招面试题汇总
Java的前景如何,好不好自学?,万字Java技术类校招面试题汇总
|
1天前
|
消息中间件 JSON Java
十五,java高级程序员面试宝典
十五,java高级程序员面试宝典
|
1天前
|
NoSQL 算法 Java
【redis源码学习】持久化机制,java程序员面试算法宝典pdf
【redis源码学习】持久化机制,java程序员面试算法宝典pdf
|
1天前
|
JavaScript 前端开发 程序员
javascript基础(入门),当上项目经理才知道,推荐程序员面试秘籍
javascript基础(入门),当上项目经理才知道,推荐程序员面试秘籍
|
1天前
|
安全 前端开发 Java
Java岗大厂面试百日冲刺 - 日积月累,每日三题【Day15
Java岗大厂面试百日冲刺 - 日积月累,每日三题【Day15
|
1天前
|
Java
阅读《代码整洁之道》总结(1),java多线程面试
阅读《代码整洁之道》总结(1),java多线程面试
|
1天前
|
NoSQL Java 关系型数据库
爱了!阿里高工纯手打金三银四Java架构面试大全,涵盖近年来1000余道大厂面试真题
爱了!阿里高工纯手打金三银四Java架构面试大全,涵盖近年来1000余道大厂面试真题