Java多线程之-----实现自己的ThreadFactory
2016-05-06 18:58
435 查看
实现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类。
2.声明3个私有的、Date类型的属性:creationDate、startDate和finishDate。
3.实现这个类的构造器。它接收名称和要执行的Runnable对象参数。存储线程的创建日期。
4.实现run()方法。存储线程的开始时间,调用父类的run()方法,存储执行的结束时间。
5.实现一个方法用来设置creationDate属性值。
6.实现一个方法用来设置startDate属性值。
7.实现一个方法用来设置finishDate属性值。
8.实现getExecutionTime()方法,用来计算线程的执行时间(结束日期与开始日期之差)。
9.覆盖toString()方法,返回线程的创建日期和执行日期。
10.创建一个实现ThreadFactory接口的MyThreadFactory类。
11.声明一个私有的、int类型的属性counter。
12.声明一个私有的、String类型的属性prefix。
13.实现这个类的构造器,初始化它的属性。
14.实现newThread()方法。创建一个MyThread对象并增加counter属性值。
15.创建一个实现Runnable接口的MyTask类。实现run()方法,令当前线程睡眠2秒。
16.实现这个例子的主类,通过创建Main类,并实现main()方法。
17.创建一个MyThreadFactory对象。
18.创建一个Task对象。
19.使用这个工厂的newThread()方法,创建一个MyThread对象来执行任务。
20.启动这个线程并等待它的结束。
21.使用toString()方法,写入关于线程的信息。
它是如何工作的…
在这个指南中,你已经通过继承Thread类来实现自定义的MyThread类。这个类有3个属性用来存储:创建日期、执行的开始日期和执行的结束日期。你已实现getExecutionTime()方法,使用开始日期和结束日期属性,返回线程已执行任务的时间。最后,你已覆盖toString()方法来产生关于线程的信息。
一旦你有自己的线程类,你已实现一个工厂来创建这个实现了ThreadFactory接口的类的对象。如果你要使用你的工厂作为一个独立的对象,这个接口的使用并不是强制的,但是如果你想要用这个工厂使用Java并发API的其他类,你必须通过实现这个接口来构建你的工厂。ThreadFactory接口只有一个方法,newThread()方法接收一个Runnable对象作为参数,并且返回一个用来执行Runnable对象的Thread对象。在你的例子中,你返回一个MyThread对象。
检查这两个类,你已实现MyTask类,这个类实现了Runnable对象。这是将在由MyThread对象管理的线程中执行的任务。一个MyTask实例令它的执行线程睡眠2秒。
在这个例子的主方法中,你已使用MyThreadFactory工厂创建一个MyThread对象,用来执行一个Task对象。执行这个程序,你将看到一条关于开始日期和线程执行的执行时间的信息。
以下截图显示这个例子产生的输出:
不止这些…
Java并发API提供Executors类来产生线程执行者,通常是ThreadPoolExecutor类的对象。你也可以使用defaultThreadFactory()方法,让这个类来获取ThreadFactory接口最基本的实现。这个方法产生的工厂所产生的基本Thread对象都属性同一个ThreadGroup对象。
你可以在你的程序中使用ThreadFactory接口用于任何目的,不一定要与执行者框架(Executor framework)有关。
package com.bird.concursey;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.ThreadFactory;
public class MyThreadFactoryimplements ThreadFactory {
private int counter;
private String name;
private List<String> stats;
public MyThreadFactory(String name) {
counter = 0;
this.name = name;
stats = new ArrayList<String>();
}
@Override
public Thread newThread(Runnable run) {
Thread t = new Thread(run, name + "-Thread-" + counter);
counter++;
stats.add(String.format("Created thread %d with name %s on%s\n" ,t.getId() ,t.getName() ,new Date()));
return t;
}
public String getStas() {
StringBuffer buffer = new StringBuffer();
Iterator<String> it = stats.iterator();
while(it.hasNext()) {
buffer.append(it.next());
buffer.append("\n");
}
return buffer.toString();
}
public static void main(String[] args){
MyThreadFactoryfactory = new MyThreadFactory("MyThreadFactory");
Task task = new Task();
Thread thread = null;
for(int i = 0; i < 10; i++) {
thread = factory.newThread(task);
thread.start();
}
System.out.printf("Factory stats:\n");
System.out.printf("%s\n",factory.getStas());
}
}
在面向对象编程的世界中,工厂模式(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类。
1 | public class MyThread extends Thread { |
1 | private Date creationDate; |
2 | private Date startDate; |
3 | private Date finishDate; |
1 | public MyThread(Runnable target, String name ){ |
2 | super (target,name); |
3 | setCreationDate(); |
4 | } |
1 | method of the parent class , and store the finish date of the execution. |
2 | @Override |
3 | public void run() { |
4 | setStartDate(); |
5 | super .run(); |
6 | setFinishDate(); |
7 | } |
1 | public void setCreationDate() { |
2 | creationDate= new Date(); |
3 | } |
1 | public void setStartDate() { |
2 | startDate= new Date(); |
3 | } |
1 | public void setFinishDate() { |
2 | finishDate= new Date(); |
3 | } |
1 | public long getExecutionTime() { |
2 | return finishDate.getTime()-startDate.getTime(); |
3 | } |
01 | @Override |
02 | public String toString(){ |
03 | StringBuilder buffer= new StringBuilder(); |
04 | buffer.append(getName()); |
05 | buffer.append( ": " ); |
06 | buffer.append( " Creation Date: " ); |
07 | buffer.append(creationDate); |
08 | buffer.append( " : Running time: " ); |
09 | buffer.append(getExecutionTime()); |
10 | buffer.append( " Milliseconds." ); |
11 | return buffer.toString(); |
12 | } |
1 | public class MyThreadFactory implements ThreadFactory { |
1 | private int counter; |
1 | private String prefix; |
1 | public MyThreadFactory(String prefix) { |
2 | this .prefix=prefix; |
3 | counter= 1 ; |
4 | } |
1 | @Override |
2 | public Thread newThread(Runnable r) { |
3 | MyThreadmyThread= new MyThread(r,prefix+ "-" +counter); |
4 | counter++; |
5 | return myThread; |
6 | } |
01 | public class MyTask implements Runnable { |
02 | @Override |
03 | public void run() { |
04 | try { |
05 | TimeUnit.SECONDS.sleep( 2 ); |
06 | } catch (InterruptedException e) { |
07 | e.printStackTrace(); |
08 | } |
09 | } |
10 | } |
1 | public class Main { |
2 | public static void main(String[] args) throws Exception { |
1 | MyThreadFactorymyFactory= new MyThreadFactory( "MyThreadFactory" ); |
1 | MyTasktask= new MyTask(); |
1 | Thread thread=myFactory.newThread(task); |
1 | thread.start(); |
2 | thread.join(); |
1 | System.out.printf( "Main: Thread information.\n" ); |
2 | System.out.printf( "%s\n" ,thread); |
3 | 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对象。执行这个程序,你将看到一条关于开始日期和线程执行的执行时间的信息。
以下截图显示这个例子产生的输出:
不止这些…
Java并发API提供Executors类来产生线程执行者,通常是ThreadPoolExecutor类的对象。你也可以使用defaultThreadFactory()方法,让这个类来获取ThreadFactory接口最基本的实现。这个方法产生的工厂所产生的基本Thread对象都属性同一个ThreadGroup对象。
你可以在你的程序中使用ThreadFactory接口用于任何目的,不一定要与执行者框架(Executor framework)有关。
package com.bird.concursey;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.ThreadFactory;
public class MyThreadFactoryimplements ThreadFactory {
private int counter;
private String name;
private List<String> stats;
public MyThreadFactory(String name) {
counter = 0;
this.name = name;
stats = new ArrayList<String>();
}
@Override
public Thread newThread(Runnable run) {
Thread t = new Thread(run, name + "-Thread-" + counter);
counter++;
stats.add(String.format("Created thread %d with name %s on%s\n" ,t.getId() ,t.getName() ,new Date()));
return t;
}
public String getStas() {
StringBuffer buffer = new StringBuffer();
Iterator<String> it = stats.iterator();
while(it.hasNext()) {
buffer.append(it.next());
buffer.append("\n");
}
return buffer.toString();
}
public static void main(String[] args){
MyThreadFactoryfactory = new MyThreadFactory("MyThreadFactory");
Task task = new Task();
Thread thread = null;
for(int i = 0; i < 10; i++) {
thread = factory.newThread(task);
thread.start();
}
System.out.printf("Factory stats:\n");
System.out.printf("%s\n",factory.getStas());
}
}
相关文章推荐
- 20145312 《Java程序设计》第十周学习总结
- spring自动扫描机制
- 关于SpringMVC的后台调试获取的值为空
- 20. Valid Parentheses-leetcode-java
- 21. Merge Two Sorted Lists-leetcode-java
- 28. Implement strStr()-leetcode-java
- 50. Pow(x, n)-leetcode-java
- 56. Merge Intervals-leetcode-java
- Ehcache是现在最流行的纯Java开源缓存框架
- 57. Insert Interval-leetcode-java
- 65. Valid Number-leetcode-java
- 73. Set Matrix Zeroes-leetcode-java
- 98. Validate Binary Search Tree-leetcode-java
- Java 常用工具类集合
- Java并发(三) JMM与volatile关键字
- Java---获得系统窗口的分辨率
- Java---获得系统窗口的分辨率
- Eclipse使用Maven构建项目运行main方法报ClassNotFoundException
- JAVA web实现可控制定时器
- eclipse下maven springMVC 整合 mybatis