Protobuf是什么

欢迎来到protocol buffer的开发者指南文档,一种语言无关、平台无关、扩展性好的用于通信协议、数据存储的结构化数据串行化方法。本文档面向希望使用protocol buffer的Java、C++或Python开发者。这个概览介绍了protocol buffer,并告诉你如何开始,你随后可以跟随编程指导深入了解protocol buffer编码方式API参考文档同样也是提供了这三种编程语言的版本,不够协议语言样式指导都是编写 .proto 文件。

什么是protocol buffer

ProtocolBuffer是用于结构化数据串行化的灵活、高效、自动的方法,有如XML,不过它更小、更快、也更简单。你可以定义自己的数据结构,然后使用代码生成器生成的代码来读写这个数据结构。你甚至可以在无需重新部署程序的情况下更新数据结构。

他们如何工作

你首先需要在一个 .proto 文件中定义你需要做串行化的数据结构信息。每个ProtocolBuffer信息是一小段逻辑记录,包含一系列的键值对。这里有个非常简单的 .proto 文件定义了个人信息:


message Person {
required string name=1;
required int32 id=2;
optional string email=3;

enum PhoneType {
MOBILE=0;
HOME=1;
WORK=2;
}

message PhoneNumber {
required string number=1;
optional PhoneType type=2 [default=HOME];
}

repeated PhoneNumber phone=4;
}

有如你所见,消息格式很简单,每个消息类型拥有一个或多个特定的数字字段,每个字段拥有一个名字和一个值类型。值类型可以是数字(整数或浮点)、布尔型、字符串、原始字节或者其他ProtocolBuffer类型,还允许数据结构的分级。你可以指定可选字段,必选字段和重复字段。你可以在proto.html找到更多关于如何编写 .proto 文件的信息。

一旦你定义了自己的报文格式(message),你就可以运行ProtocolBuffer编译器,将你的 .proto 文件编译成特定语言的类。

为什么不用XML?

ProtocolBuffer拥有多项比XML更高级的串行化结构数据的特性,ProtocolBuffer:

    更简单
    小3-10倍
    快20-100倍
    更少的歧义
    可以方便的生成数据存取类 

例如,让我们看看如何在XML中建模Person的name和email字段:


<person>
<name>John Doe</name>
<email>jdoe@example.com</email>
</person>

对应的ProtocolBuffer报文则如下:

ProtocolBuffer的文本表示
这不是正常时使用的二进制数据

person {
name: "John Doe"
email: "jdoe@example.com"
}

当这个报文编码到ProtocolBuffer的二进制格式时(上面的文本仅用于调试和编辑),它只需要28字节和100-200ns的解析时间。而XML的版本需要69字节(除去空白)和 5000-10000ns的解析时间。

设计模式之创建型模式

##创建型模式
这六个模式都是与创建对象相关的

  • 简单工厂模式(Simple Factory);
  • 工厂方法模式(Factory Method);
  • 抽象工厂模式(Abstract Factory);
  • 创建者模式(Builder);
  • 原型模式(Prototype);
  • 单例模式(Singleton);

简单工厂模式(Simple Factory);

工厂方法模式(Factory Method);

建立一个工厂类,对实现同一接口的类进行实例化创建。

``
package design.pattern.factory;

/**
* Created by Aaron on 15/9/13.
*/
public interface IParser {
String parse(Object obj);
}
package design.pattern.factory;

/**
* Created by Aaron on 15/9/13.
*/
public class JSONParser implements IParser{
@Override
public String parse(Object obj) {
//create json string
return "{class:"+obj.getClass()+"}";
}
}
package design.pattern.factory;

/**
* Created by Aaron on 15/9/13.
*/
public class XMLParser implements IParser{
@Override
public String parse(Object obj) {
//create xml string....
return "<object><class>"+obj.getClass()+"</class></object>";
}
}
package design.pattern.factory;

/**
* Created by Aaron on 15/9/13.
*/
public class ParserFactory {
public static final String TYPE_XML="xml";
public static final String TYPE_JSON="json";
public static IParser buildParser(String type){
switch (type){
case ParserFactory.TYPE_XML:return new XMLParser();
case ParserFactory.TYPE_JSON:return new JSONParser();
}
return null;
}

public static void main(String[] args){
IParser parser= ParserFactory.buildParser(ParserFactory.TYPE_JSON);
System.out.print(parser.parse(parser));
}
}

//output {class:JSONParser}

抽象工厂模式(Abstract Factory);

工厂方法,每创建一个新的类时,就要个性类工厂类,这样拓展性比较差,如何能通过不个性工厂类而进行扩展呢。这里就用到了抽象工厂模式,就是创建多个工厂,一旦要增加新的类型就增加一个新的工厂,不需要修改现有代码。

基于上面代码将ParserFactory工厂类用一个抽象工厂类和两个子工厂类进行代替
package design.pattern.abstractfactory;

import design.pattern.factory.*;

/**
* Created by Aaron on 15/9/13.
*/
public abstract class AbstractParserFactory {
abstract IParser create();
}

package design.pattern.abstractfactory;

/**
* Created by Aaron on 15/9/13.
*/
public class JSONParserFactory extends AbstractParserFactory {
@Override
IParser create() {
return new JSONParser();
}
}

package design.pattern.abstractfactory;

/**
* Created by Aaron on 15/9/13.
*/
public class XMLParserFactory extends AbstractParserFactory {
@Override
IParser create() {
return new XMLParser();
}
}

建造者模式(Builder);

GoF这样定义:

建造者模式:是将一个复杂的对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

咱们这里以创建应用为例,这里我们创建两个应用,考试系统和CRM系统,创建过程是,需求->原型图->开发计划->表设计->架构设计->功能实现->测试->交付 大概是这样一个简单的过程,这里就会看到同样的构建过程得到不同的表示。
package design.pattern.builder;

import java.util.Vector;

/**
* Created by Aaron on 15/9/13.
*/
public class Project {

private Vector<String> impleProcess=new Vector<String>();
public void process(String imple){
impleProcess.add(imple);
}
public Vector<String> getImpleProcess() {
return impleProcess;
}

}

package design.pattern.builder;

/**
* Created by Aaron on 15/9/13.
*/
public interface IProjectBuilder {
Project getProject();
void makeRequirement();

void makePrototype();

void makeScheduler();

void makeTables();

void makeAppFrameWork();

void programming();

void test();

void delivery();
}

package design.pattern.builder;

/**
* Created by Aaron on 15/9/13.
*/
public class ExamProjectBuilder implements IProjectBuilder {
private Project project;

public ExamProjectBuilder() {
this.project = new Project();
}

public Project getProject() {
return project;
}

@Override
public void makeRequirement() {
this.project.process("创建考试系统需求");

}

@Override
public void makePrototype() {
this.project.process("创建考试原型");
}

@Override
public void makeScheduler() {
this.project.process("创建考试计划");
}

@Override
public void makeTables() {
this.project.process("创建考试系统表");
}

@Override
public void makeAppFrameWork() {
this.project.process("创建考试应用架构");
}

@Override
public void programming() {
this.project.process("考试应用代码实现");
}

@Override
public void test() {
this.project.process("测试考试应用");
}

@Override
public void delivery() {
this.project.process("交付考试应用");
}
}

package design.pattern.builder;

/**
* Created by Aaron on 15/9/13.
*/
public class CRMProjectBuilder implements IProjectBuilder {
public CRMProjectBuilder() {
this.project = new Project();
}

public Project getProject() {
return project;
}

private Project project;

@Override
public void makeRequirement() {
this.project.process("创建CRM系统需求");
}

@Override
public void makePrototype() {
this.project.process("创建CRM原型");
}

@Override
public void makeScheduler() {
this.project.process("创建CRM计划");
}

@Override
public void makeTables() {
this.project.process("创建CRM系统表");
}

@Override
public void makeAppFrameWork() {
this.project.process("创建CRM应用架构");
}

@Override
public void programming() {
this.project.process("CRM应用代码实现");
}

@Override
public void test() {
this.project.process("测试CRM应用");
}

@Override
public void delivery() {
this.project.process("交付CRM应用");
}
}

package design.pattern.builder;

/**
* Created by Aaron on 15/9/13.
*/
public class Director {
private IProjectBuilder builder;
public Director(IProjectBuilder builder){
this.builder=builder;
}
public Project process(){
this.builder.makeRequirement();
this.builder.makePrototype();
this.builder.makeScheduler();
this.builder.makeAppFrameWork();
this.builder.makeTables();
this.builder.programming();
this.builder.test();
this.builder.delivery();
return builder.getProject();
}

public static void main(String[] args){
Director director = new Director(new CRMProjectBuilder());
Project project = director.process();
System.out.println(project.getImpleProcess());
}
}

//输出 [创建CRM系统需求, 创建CRM原型, 创建CRM计划, 创建CRM应用架构, 创建CRM系统表, CRM应用代码实现, 测试CRM应用, 交付CRM应用]

原型模式(Prototype);

GoF这样定义:

用原型实例指定创建对象的种类,并且通过拷贝这个原型来创建新的对象。

package design.pattern.prototype;

import java.io.*;
import java.util.Vector;

/**
* Created by Aaron on 15/9/13.
*/
public class DeepClonePrototype implements Cloneable,Serializable {
public Vector<String> attrs=new Vector<String>();

public Object deepClone() throws CloneNotSupportedException, IOException, ClassNotFoundException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(this);
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais);
return ois.readObject();
}

public static void main(String[] args) throws Exception{
Object pro=new DeepClonePrototype().deepClone();
System.out.println(pro.getClass());
}

}

单例模式(Singleton);

保证一个类仅有一个实例,并提供一个访问它的全局访问点。

package design.pattern.singleton;

/**
* Created by Aaron on 15/9/11.
*/
public class Singleton {
private Singleton() {

}

private static Singleton instance = null;

private static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
return instance = new Singleton();
} else {
return instance;
}
}
} else {
return instance;
}
}

public String getName() {
return Singleton.class.getName();
}

public static void main(String args[]) {
Singleton instance = Singleton.getInstance();
System.out.print(instance.getName());
}

}

设计模式之结构型模式

##结构型模式

描述在面向对象设计中,类和对象的几种结构关系,设计好了会为后续代码的维护带来很大的方便。

  • 外观模式(Facade);
  • 适配器模式(Adapter);
  • 代理模式(Proxy);
  • 装饰模式(Decorator);
  • 桥模式(Bridge);
  • 组合模式(Composite);
  • 享元模式(Flyweight);

###外观模式(Facade)又称门面模式;
GoF这样定义:

为子系统中的一组接口提供一个一致的界面, Facade 模式定义了一个高层 接口,这个接口使得这一子系统更加容易使用。

外观模式,在我理解就是给一组对象提供一个对外统计的操作方式 ,让外部使用者不用操心内部工作。如一个汽车,一个电脑,你点开机,硬盘,CPU,内存,显卡就都开始工作了,关机时也一样。这里对我们操作者来说其实就是一个开关。

``
package design.pattern.facade;

/**
* Created by Aaron on 15/9/14.
*/
public class User {
public static void main(String[] args)throws InterruptedException{
Computer computer=new Computer();
computer.startup();
System.out.println("--------shutdown-----------");
computer.shutdown();
}
}

package design.pattern.facade;
/**
* Created by Aaron on 15/9/14.
*/
public class Computer {
private CPU cpu;
private Memory memory;
private GraphicsCard graphicsCard;
private Disk disk;

public Computer() {
this.cpu = new CPU();
this.memory = new Memory();
this.graphicsCard = new GraphicsCard();
this.disk = new Disk();
}

public void startup(){
this.cpu.startup();
this.memory.startup();
this.disk.startup();
this.graphicsCard.startup();
}
public void shutdown(){
this.graphicsCard.shutdown();
this.disk.shutdown();
this.memory.shutdown();
this.cpu.shutdown();
}



}

package design.pattern.facade;

/**
* Created by Aaron on 15/9/14.
*/
public class CPU {
public void startup(){
System.out.println(this.getClass().getSimpleName()+"启动");
}
public void shutdown(){
System.out.println(this.getClass().getSimpleName()+"关闭");
}
}

package design.pattern.facade;

/**
* Created by Aaron on 15/9/14.
*/
public class Disk {
public void startup(){
System.out.println(this.getClass().getSimpleName()+"启动");
}
public void shutdown(){
System.out.println(this.getClass().getSimpleName()+"关闭");
}
}

package design.pattern.facade;

/**
* Created by Aaron on 15/9/14.
*/
public class GraphicsCard {
public void startup(){
System.out.println(this.getClass().getSimpleName()+"启动");
}
public void shutdown(){
System.out.println(this.getClass().getSimpleName()+"关闭");
}
}

package design.pattern.facade;

/**
* Created by Aaron on 15/9/14.
*/
public class Memory {
public void startup(){
System.out.println(this.getClass().getSimpleName()+"启动");
}
public void shutdown(){
System.out.println(this.getClass().getSimpleName()+"关闭");
}
}

输出结果:

CPU启动
Memory启动
Disk启动
GraphicsCard启动
--------shutdown-----------
GraphicsCard关闭
Disk关闭
Memory关闭
CPU关闭

###适配器模式(Adapter);
GoF这样定义:

将一个类的接口转换成客户希望的另外一个接口。 Adapter 模式使得原本 由于接口不兼容而不能一起工作的那些类可以一起工作。

我的事例理解:如咱们家中常用的洗衣机,当我们要与我们的水龙头进行对接时,中间要借助一个中间者“转换头”,它在这里就起到了适配作用。

``
package design.pattern.adapter;

/**
* Created by Aaron on 15/9/14.
*/
public class WashingMachine {
public void connectPort(IWashFaucetAdapter washportadapter){
System.out.print(washportadapter.outToWashingPort()+" success!");
}
}

package design.pattern.adapter;

/**
* Created by Aaron on 15/9/14.
*/
public interface IWashFaucetAdapter {
String outToWashingPort();
}

package design.pattern.adapter;

/**
* Created by Aaron on 15/9/14.
*/
public class WashingFaucetAdapter extends Faucet implements IWashFaucetAdapter{

public String outToWashingPort(){
return "transform"+this.port()+" to washing port!";
}
}

package design.pattern.adapter;

/**
* Created by Aaron on 15/9/14.
* 水龙头
*/

public class Faucet {
public String port(){
System.out.print("facucet port .....");
return "facucet port";
}
}

package design.pattern.adapter;

/**
* Created by Aaron on 15/9/14.
*/
public class User {
public static void main(String[] args){
// 创建水龙头、洗衣机、镶接头
WashingMachine washingMachine=new WashingMachine();
WashingFaucetAdapter washingFaucetAdapter= new WashingFaucetAdapter();
// 进行适配
washingMachine.connectPort(washingFaucetAdapter);

}
}

输出结果:

facucet port .....transformfacucet port to washing port! success!

###代理模式(Proxy);
GoF这样定义:

为其他对象提供一个代理以控制对这个对象的访问。

这里就以找工作为例吧,现在我们找工作都会通过找工作平台来进行找工作,因为他们有资源,他们比较专业。我们告诉他们要找什么样的工作他们就会给我们推荐什么样的工作,在这个环节中,类似51job,100offer这样的平台就是所谓的招聘代理。
他代理公司进行招人。同时也方便了我们去找工作。

下面是代码实现:

package design.pattern.proxy;

/**
* Created by Aaron on 15/9/14.
*/
public interface IRecruitment {
void recruitment(String user);
}

package design.pattern.proxy;

/**
* Created by Aaron on 15/9/14.
*/
public class FounderWork implements IRecruitment{
public void recruitment(String user){
System.out.println(this.getClass().getSimpleName()+"招聘员工"+user+"成功!");
}
}

package design.pattern.proxy;

/**
* Created by Aaron on 15/9/14.
*/
public class WorkProxy implements IRecruitment {
private IRecruitment recruitment;

public WorkProxy() {
this.recruitment = new FounderWork();
}

@Override
public void recruitment(String user) {
before();
this.recruitment.recruitment(user);
after();
}

public void before() {
System.out.println(this.getClass().getSimpleName() + "进行招聘前工作准备!");
}

public void after() {
System.out.println(this.getClass().getSimpleName() + "进行招聘完成后工作收尾!");
}

}


package design.pattern.proxy;

/**
* Created by Aaron on 15/9/14.
*/
public class User {
public static void main(String[] args){
new WorkProxy().recruitment("Aaron");
}
}

输出:

WorkProxy进行招聘前工作准备!
FounderWork招聘员工Aaron成功!
WorkProxy进行招聘完成后工作收尾!

###装饰模式(Decorator);
GoF这样定义:

动态地给一个对象添加一些额外的职责。就扩展功能而言, Decorator 模 式比生成子类方式更为灵活。

我们可以拿我们的扩音器为例,假如一个mp3的有声音,那么它的声音不是很大,稍微远一点我们就不能听到了,这里就会用一个扩音器,放在mp3旁边,离稍微远点也能享受音乐的快乐了。

这里,扩音器就是装饰器,他使mp3的声音变大。有时扩音器也可以改变声音的音质,变的更好听。

下面是代码实现:

package design.pattern.decorator;

/**
* Created by Aaron on 15/9/14.
*/
public interface ISoundable {
void sound();
}

package design.pattern.decorator;

/**
* Created by Aaron on 15/9/14.
*/
public class MP3 implements ISoundable{
public void sound(){
System.out.println("small sound from mp3!");
}
}

package design.pattern.decorator;

/**
* Created by Aaron on 15/9/14.
*/
public class SoundDecorator implements ISoundable {
private ISoundable soundable;

public SoundDecorator(ISoundable soundable) {
this.soundable = soundable;
}

public void sound(){
this.soundable.sound();
System.out.println("make sound beautiful");
System.out.println("make sound aloud ");
}
}

package design.pattern.decorator;

/**
* Created by Aaron on 15/9/14.
*/
public class User {
public static void main(String[] args){
new SoundDecorator(new MP3()).sound();
}
}

输出:

small sound from mp3!
make sound beautiful
make sound aloud 

###桥接模式(Bridge);
GoF这样定义:

将抽象部分与它的实现部分分离,使它们都可以独立地变化。

这里还举一个生活中常用到的例子,洗衣机有多种,但我们当我们没有接到水龙头上的管子时,我们可以去商店里买,这里可能会有大小长短各不相同的管子,但都可以与我们的洗衣机相连接进行使用。

这里我们变化的是多种洗衣机和多种管子,我们为洗衣机做一个抽像类。可以设置不同的管子。

``
package design.pattern.bridge;

/**
* Created by Aaron on 15/9/14.
*/
public interface IPip {
String color();
}

package design.pattern.bridge;

/**
* Created by Aaron on 15/9/14.
* 水龙头
*/

public class RedPip implements IPip{
public String color(){
return "Red";
}
}

package design.pattern.bridge;

/**
* Created by Aaron on 15/9/14.
* 水龙头
*/

public class BluePip implements IPip{
public String color(){
return "blue pip";
}
}


package design.pattern.bridge;

/**
* Created by Aaron on 15/9/14.
*/
public abstract class AbstractWashingMachine {
private IPip pip;

public IPip getPip() {
return pip;
}

public void setPip(IPip pip) {
this.pip = pip;
System.out.println(this.getClass().getSimpleName()+" set "+pip.color()+" "+pip.getClass().getSimpleName());
}
}


package design.pattern.bridge;

/**
* Created by Aaron on 15/9/14.
*/
public class ChinaWashingMachine extends AbstractWashingMachine {
}

package design.pattern.bridge;

/**
* Created by Aaron on 15/9/14.
*/
public class HaierWashingMachine extends AbstractWashingMachine {
}

package design.pattern.bridge;

/**
* Created by Aaron on 15/9/14.
*/
public class User {
public static void main(String[] args){
new HaierWashingMachine().setPip(new BluePip());
new HaierWashingMachine().setPip(new RedPip());
new ChinaWashingMachine().setPip(new BluePip());
}
}

输出:

HaierWashingMachine set blue pip BluePip
HaierWashingMachine set Red RedPip
ChinaWashingMachine set blue pip BluePip

###组合模式(Composite);
GoF这样定义:

将对象组合成树形结构以表示“部分-整体”的层次结构。Composite使 得客户对单个对象和复合对象的使用具有一致性。

这里我们最常见的就是公司与部门的关系,其实就是整体与部分的关系。

代码

package design.pattern.composite;

import java.util.Vector;

/**
* Created by Aaron on 15/9/14.
*/
public abstract class AbstractCompany {
private String name;
private Vector<AbstractCompany> companys=new Vector<AbstractCompany>();
public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}
public void display(int deep) {
StringBuilder sb=new StringBuilder();
for(int i=0;i<deep;i++){
sb.append("\t");
}
sb.append(this.getName());
System.out.println(sb.toString());
int l = this.getCompanys().size();
if (l > 0) {
for (int i = 0; i < l; i++) {
this.getCompanys().get(i).display(deep+2);
}
}
}
public Vector<AbstractCompany> getCompanys() {
return companys;
}
public void removeCompany(AbstractCompany company){
this.companys.remove(company);
}
public void addCompany(AbstractCompany company) {
this.companys.add(company);
}
}

package design.pattern.composite;

/**
* Created by Aaron on 15/9/14.
*/
public class Company extends AbstractCompany {
public Company(String name) {
this.setName(name);
}

}

package design.pattern.composite;

/**
* Created by Aaron on 15/9/14.
*/
public class TechDepartment extends AbstractCompany {
public TechDepartment() {
}
public TechDepartment(String name) {
this.setName(name);
}
}

package design.pattern.composite;

/**
* Created by Aaron on 15/9/14.
*/
public class UIDepartment extends AbstractCompany {
public UIDepartment(String name) {
this.setName(name);
}

public UIDepartment() {
}
}

package design.pattern.composite;

/**
* Created by Aaron on 15/9/14.
*/
public class CEO {
public static void main(String[] args) {
AbstractCompany company = new Company("总公司");
AbstractCompany abc = new TechDepartment("技术一部");
company.addCompany(abc);
abc = new TechDepartment("技术二部");
company.addCompany(abc);
abc = new TechDepartment("技术三部");
company.addCompany(abc);
abc = new UIDepartment("UI一部");
company.addCompany(abc);
abc = new UIDepartment("UI二部");
company.addCompany(abc);
abc = new UIDepartment("UI三部");
company.addCompany(abc);
AbstractCompany abc1 = new UIDepartment("UI一组");
abc.addCompany(abc1);
abc1 = new UIDepartment("UI二组");
abc.addCompany(abc1);
abc1 = new UIDepartment("UI三组");
abc.addCompany(abc1);
company.display(0);
}
}


输出:

总公司
        技术一部
        技术二部
        技术三部
        UI一部
        UI二部
        UI三部
                UI一组
                UI二组
                UI三组

###享元模式(Flyweight)
GoF这样定义:

运用共享技术有效地支持大量细粒度的对象。

咱们这里会想到数据库连接池,对,就是它,咱们先看一下类图。

`示例代码如下:`
package design.pattern.flayweight;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Vector;

/**
* Created by Aaron on 15/9/14.
*/
public class ConnectionPool {
private Vector<Connection> pool;
private static ConnectionPool instance;
private int poolSize=10;
private String url = "jdbc:mysql://127.0.0.1:3306/mysql";
private String username = "root";
private String password = "root";
private String driverClassName = "com.mysql.jdbc.Driver";
private ConnectionPool(){
this.pool=new Vector<Connection>();

for (int i = 0; i < poolSize; i++) {
try {
Class.forName(driverClassName);
pool.add(DriverManager.getConnection(url, username, password));
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
}
}

public static synchronized ConnectionPool getInstance(){
if(instance==null){
return instance=new ConnectionPool();
}
return instance;
}

public synchronized Connection getConnection(){
Connection connection=null;
if(pool.size()>0){
connection=pool.get(0);
pool.remove(connection);
}
return connection;
}

public synchronized void release(Connection conn){
pool.add(0,conn);
}

}

package design.pattern.flayweight;

import java.sql.Connection;

/**
* Created by Aaron on 15/9/14.
*/
public class User {
public static void main(String args[]){
ConnectionPool pool=ConnectionPool.getInstance();
Connection connection=pool.getConnection();
System.out.println(connection);
connection=pool.getConnection();
System.out.println(connection);
pool.release(connection);
connection=pool.getConnection();
System.out.println(connection);
}
}


输出:

com.mysql.jdbc.JDBC4Connection@2d8e6db6
com.mysql.jdbc.JDBC4Connection@23ab930d
com.mysql.jdbc.JDBC4Connection@23ab930d

JAVA设计模式之行为型模式

##行为型模式

对象的创建和结构定义好后,就是他们的行为的设计了。

  • 模板方法模式(Template Method);
  • 观察者模式(Observer);
  • 状态模式(State);
  • 策略模式(Strategy);
  • 职责链模式(Chain of Responsibility);
  • 命令模式(Command);
  • 访问者模式(Visitor);
  • 调停者模式(Mediator);
  • 备忘录模式(Memento);
  • 迭代器模式(Iterator);
  • 解释器模式(Interpreter);

模板方法模式(Template Method);

GoF这样定义:

定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。
Template Method使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。

这里我们以画布上画画为例,我们定义一抽象类,其中定义一个渲染方法,渲染时有两个步骤,一个画背景,二能画主体,三加印章。
咱们这里画一个圆和画一个矩形,抽象类中定义渲染时的先后流程,具体的实现有具体的子类进行实现。

代码如下:

package design.pattern.temlatemothod;

/**
* Created by Aaron on 15/9/16.
*/
public abstract class AbstractShape {
public void render(){
this.drawBackground();
this.drawGraphics();
this.drawSignature();
}
abstract void drawSignature();
abstract void drawBackground();
abstract void drawGraphics();

}

package design.pattern.temlatemothod;

/**
* Created by Aaron on 15/9/16.
*/
public class CircleShape extends AbstractShape {
@Override
public void drawSignature() {
System.out.println("draw circle signature!");
}

@Override
public void drawBackground() {
System.out.println("draw circle background! ");
}

@Override
public void drawGraphics() {
System.out.println("draw circle graphics!");
}
}

package design.pattern.temlatemothod;

/**
* Created by Aaron on 15/9/16.
*/
public class RectShape extends AbstractShape {
@Override
public void drawSignature() {
System.out.println("draw rect signature!");
}

@Override
public void drawBackground() {
System.out.println("draw rect background! ");
}

@Override
public void drawGraphics() {
System.out.println("draw rect graphics!");
}
}

package design.pattern.temlatemothod;

/**
* Created by Aaron on 15/9/16.
*/
public class User {
public static void main(String args[]){
new CircleShape().render();
System.out.println("-----");
new RectShape().render();
}
}

输出结果:

draw circle background! 
draw circle graphics!
draw circle signature!
-----
draw circle background! 
draw circle graphics!
draw circle signature!

观察者模式(Observer);

GoF这样定义:

定义对象间的一种一对多的依赖关系 , 以便当一个对象的状态发生改变时 , 所有依赖于它的对象都得到通知并自动刷新。

我们常常会遇到,当一个事件发生时,会有一些监听者进行相应的响应。这里我们的例子是, 当GPS发生变化时,它的订阅者的update的方法就会被调用。

`下面是示例代码:`
package design.pattern.observer;

import java.lang.reflect.Array;
import java.util.ArrayList;

/**
* Created by Aaron on 15/9/16.
*/
public abstract class Subject {
private ArrayList<Observer> observers=new ArrayList<Observer>();
public void addObserver(Observer observer){
this.observers.add(observer);
}
public void removeObserver(Observer observer){
this.observers.remove(observer);
}
public void notifyObserver(){
for(Observer observer:observers){
observer.update(this);
}
}
}

package design.pattern.observer;

import java.awt.*;

/**
* Created by Aaron on 15/9/16.
*/
public class GPSSubject extends Subject {
private Point point;
public void move(Point point){
this.point=point;
this.notifyObserver();
}
}

package design.pattern.observer;

/**
* Created by Aaron on 15/9/16.
*/
public abstract class Observer {
public Observer(){

}
public abstract void update(Subject subject);

}


package design.pattern.observer;

/**
* Created by Aaron on 15/9/16.
*/
public class MapObserver extends Observer {
@Override
public void update(Subject subject) {
System.out.println(this.getClass().getSimpleName()+"_"+this.hashCode()+" observer:"+subject.getClass().getSimpleName()+" position changed;");
}
}

package design.pattern.observer;

import java.awt.*;

/**
* Created by Aaron on 15/9/16.
*/
public class User {
public static void main(String[] args){
GPSSubject subject=new GPSSubject();
subject.addObserver(new MapObserver());
Observer observer1=null;
subject.addObserver(observer1=new MapObserver());
subject.move(new Point(200, 400));
System.out.println("remove one observer from subject's observer list!");
subject.removeObserver(observer1);
subject.move(new Point(200,400));
}
}

状态模式(State);

GoF这样定义: 允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它
所属的类。

以下是示例代码:

package design.pattern.state;

/**
* Created by Aaron on 15/9/20.
*/
public class Context extends AbstractLifeState {
public static OpeningState openingState = new OpeningState();
public static ClosingState closingState = new ClosingState();
public static RunningState runningState = new RunningState();
public static StoppingState stoppingState = new StoppingState();
private AbstractLifeState lifeState;

public Context() {
}

public AbstractLifeState getLifeState() {
return lifeState;
}

public void setLifeState(AbstractLifeState lifeState) {
this.lifeState = lifeState;
this.lifeState.setContext(this);
}

@Override
public void open() {
this.lifeState.open();
}

@Override
public void close() {
this.lifeState.close();
}

@Override
public void run() {
this.lifeState.run();
}

@Override
public void stop() {
this.lifeState.stop();
}
}

package design.pattern.state;

/**
* Created by Aaron on 15/9/20.
*/
public abstract class AbstractLifeState {
protected Context context;

public void setContext(Context context) {
this.context = context;
}

public abstract void open();
public abstract void close();
public abstract void run();
public abstract void stop();
}

package design.pattern.state;

/**
* Created by Aaron on 15/9/20.
*/
public class OpeningState extends AbstractLifeState {
@Override
public void open() {
System.out.println(this.getClass().getSimpleName() + ": operate open");
}

@Override
public void close() {
System.out.println(this.getClass().getSimpleName() + ": operate close");
this.context.setLifeState(Context.closingState);
}

@Override
public void run() {
System.out.println(this.getClass().getSimpleName() + ": operate run");
this.context.setLifeState(Context.runningState);
}

@Override
public void stop() {
System.out.println(this.getClass().getSimpleName()+": operate stop");
this.context.setLifeState(Context.stoppingState);
}
}

package design.pattern.state;

/**
* Created by Aaron on 15/9/20.
*/
public class RunningState extends AbstractLifeState {
@Override
public void open() {
System.out.println(this.getClass().getSimpleName() + ": operate open");
context.setLifeState(Context.openingState);
}

@Override
public void close() {
System.out.println(this.getClass().getSimpleName()+": operate close");
context.setLifeState(Context.closingState);
}

@Override
public void run() {
System.out.println(this.getClass().getSimpleName()+": operate run");
}

@Override
public void stop() {
System.out.println(this.getClass().getSimpleName()+": operate stop");
context.setLifeState(Context.stoppingState);
}
}

package design.pattern.state;

/**
* Created by Aaron on 15/9/20.
*/
public class StoppingState extends AbstractLifeState {
@Override
public void open() {
System.out.println(this.getClass().getSimpleName() + ": operate open");
}

@Override
public void close() {
System.out.println(this.getClass().getSimpleName()+": operate close");
}

@Override
public void run() {
System.out.println(this.getClass().getSimpleName()+": operate run");
}

@Override
public void stop() {
System.out.println(this.getClass().getSimpleName()+": operate stop");
}
}

package design.pattern.state;

/**
* Created by Aaron on 15/9/20.
*/
public class ClosingState extends AbstractLifeState {
@Override
public void open() {
System.out.println(this.getClass().getSimpleName() + ": operate open");
context.setLifeState(Context.openingState);
}

@Override
public void close() {
System.out.println(this.getClass().getSimpleName() + ": operate close");
}

@Override
public void run() {
System.out.println(this.getClass().getSimpleName()+": operate run");
context.setLifeState(Context.runningState);
}

@Override
public void stop() {
System.out.println(this.getClass().getSimpleName()+": operate stop");
context.setLifeState(Context.stoppingState);
}
}

package design.pattern.state;

import design.pattern.flayweight.ConnectionPool;

/**
* Created by Aaron on 15/9/20.
*/
public class User {
public static void main(String[] args){
Context context=new Context();
context.setLifeState(Context.closingState);
context.open();
context.run();
context.close();

}
}

策略模式(Strategy);

GoF这样定义:

定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。

计算器的实现,其中计算的

以下是示例代码:

package design.pattern.strategy;

/**
* Created by Aaron on 15/9/21.
*/
public interface ICalculate {
double calculate(double a,double b);
}

package design.pattern.strategy;

/**
* Created by Aaron on 15/9/21.
*/
public class AddCalculate implements ICalculate {
public double calculate(double a, double b) {
return a+b;
}
}

package design.pattern.strategy;

/**
* Created by Aaron on 15/9/21.
*/
public class DivisionCalculate implements ICalculate {
public double calculate(double a, double b) {
return a/b;
}
}

package design.pattern.strategy;

/**
* Created by Aaron on 15/9/21.
*/
public class SubtractionCalculate implements ICalculate {
public double calculate(double a, double b) {
return a-b;
}
}

package design.pattern.strategy;

/**
* Created by Aaron on 15/9/21.
*/
public class Context {
private ICalculate calculate;
public Context(ICalculate calculate){
this.calculate=calculate;
}

public ICalculate getCalculate() {
return calculate;
}

public void setCalculate(ICalculate calculate) {
this.calculate = calculate;
}

public double calculate(double a,double b){
return this.calculate.calculate(a,b);
}
}

package design.pattern.strategy;

/**
* Created by Aaron on 15/9/21.
*/
public class User {
public static void main(String args[]){
Context context =new Context(new AddCalculate());
double result=context.calculate(20.0,30.3);
System.out.println(result);
context.setCalculate(new DivisionCalculate());
System.out.println(context.calculate(20,40));
}
}

结果输出:

50.3
0.5

职责链模式(Chain of Responsibility);

GoF这样定义:

典型的事例就是我们在Spring中的拦截器和Servlet中的Filter,它们都是现成的责任链模式。

`以下是示例代码:`
package design.pattern.responsibilitychain;

/**
* Created by Aaron on 15/9/29.
*/
public abstract class Handler {
protected Handler successor;

public abstract void process();

public Handler getSuccessor() {
return successor;
}

public void setSuccessor(Handler successor) {
this.successor = successor;
}
}

package design.pattern.responsibilitychain;

/**
* Created by Aaron on 15/9/29.
*/
public class LoggerHandler extends Handler {
@Override
public void process() {
if(getSuccessor()!=null){
System.out.println(getClass().getSimpleName()+",处理请求,并调用下一个处理者");
getSuccessor().process();
}else{
System.out.println(getClass().getSimpleName()+",仅处理,无下一处理者");
}
}
}

package design.pattern.responsibilitychain;

/**
* Created by Aaron on 15/9/29.
*/
public class ValidateHandler extends Handler {
@Override
public void process() {
if(getSuccessor()!=null){
System.out.println(getClass().getSimpleName()+",处理请求,并调用下一个处理者");
getSuccessor().process();
}else{
System.out.println(getClass().getSimpleName()+",仅处理,无下一处理者");
}
}
}

package design.pattern.responsibilitychain;

/**
* Created by Aaron on 15/9/29.
*/
public class User {
public static void main(String[] args) {
Handler validate = new ValidateHandler();
Handler handler = new LoggerHandler();
validate.setSuccessor(handler);
validate.process();
}
}

输出:

ValidateHandler,处理请求,并调用下一个处理者
LoggerHandler,仅处理,无下一处理者

命令模式(Command);

GoF这样定义:

将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数 化;对请求排队或记录请求日志,以及支持可取消的操作。

AudioPlayer系统(转)

  小女孩茱丽(Julia)有一个盒式录音机,此录音机有播音(Play)、倒带(Rewind)和停止(Stop)功能,录音机的键盘便是请求者(Invoker)角色;茱丽(Julia)是客户端角色,而录音机便是接收者角色。Command类扮演抽象命令角色,而PlayCommand、StopCommand和RewindCommand便是具体命令类。茱丽(Julia)不需要知道播音(play)、倒带(rewind)和停止(stop)功能是怎么具体执行的,这些命令执行的细节全都由键盘(Keypad)具体实施。茱丽(Julia)只需要在键盘上按下相应的键便可以了。

  录音机是典型的命令模式。录音机按键把客户端与录音机的操作细节分割开来。

`以下是示例代码:`
package design.pattern.command;

/**
* Created by Aaron on 15/9/29.
*/
public class AudioPlay {
public void play(){
System.out.println("播放....");
}
public void rewind(){
System.out.println("倒带....");
}
public void stop(){
System.out.println("停止....");
}

}

package design.pattern.command;

/**
* Created by Aaron on 15/9/29.
*/
public interface Command {
void execute();
}


package design.pattern.command;

/**
* Created by Aaron on 15/9/29.
*/
public class PlayCommand implements Command {
private AudioPlay audioPlay;

public PlayCommand(AudioPlay audioPlay) {
this.audioPlay = audioPlay;
}

public void execute() {
this.audioPlay.play();
}
}

package design.pattern.command;

/**
* Created by Aaron on 15/9/29.
*/
public class RewindCommand implements Command {
private AudioPlay audioPlay;

public RewindCommand(AudioPlay audioPlay) {
this.audioPlay = audioPlay;
}
public void execute() {
this.audioPlay.rewind();
}
}

package design.pattern.command;

/**
* Created by Aaron on 15/9/29.
*/
public class StopCommand implements Command {
private AudioPlay audioPlay;

public StopCommand(AudioPlay audioPlay) {
this.audioPlay = audioPlay;
}
public void execute() {
this.audioPlay.stop();
}
}

package design.pattern.command;

/**
* Created by Aaron on 15/9/29.
*/
public class Keypad {
private Command playCommand;
private Command rewindCommand;
private Command stopCommand;

public void setPlayCommand(Command playCommand) {
this.playCommand = playCommand;
}

public void setRewindCommand(Command rewindCommand) {
this.rewindCommand = rewindCommand;
}

public void setStopCommand(Command stopCommand) {
this.stopCommand = stopCommand;
}

public void play(){
playCommand.execute();
}
public void rewind(){
rewindCommand.execute();
}
public void stop(){
stopCommand.execute();
}
}

package design.pattern.command;

/**
* Created by Aaron on 15/9/29.
*/
public class User {
public static void main(String[] args) {
AudioPlay audioPlay = new AudioPlay();
PlayCommand playCommand = new PlayCommand(audioPlay);
RewindCommand rewindCommand = new RewindCommand(audioPlay);
StopCommand stopCommand = new StopCommand(audioPlay);

Keypad keypad=new Keypad();
keypad.setPlayCommand(playCommand);
keypad.setRewindCommand(rewindCommand);
keypad.setStopCommand(stopCommand);

keypad.play();
keypad.rewind();
keypad.stop();
keypad.play();
keypad.stop();

}
}

输出结果:

播放....
倒带....
停止....
播放....
停止....

访问者模式(Visitor);

GoF这样定义:

表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元
素的类的前提下定义作用于这些元素的新操作。

`以下是示例代码:`
```
## 调停者模式(Mediator);
GoF这样定义:
>用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互

<div class="col-xs-12">
<img src='' class='col-lg-offset-3 col-lg-6 col-xs-12 thumbnail'/>
</div>
`以下是示例代码:`
```java
## 备忘录模式(Memento); GoF这样定义: > 在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到保存的状态。
`以下是示例代码:`
```
## 迭代器模式(Iterator);
GoF这样定义:
>提供一种方法顺序访问一个聚合对象中各个元素,而又不需暴露该对象的内部表示。
<div class="col-xs-12">
<img src='' class='col-lg-offset-3 col-lg-6 col-xs-12 thumbnail'/>
</div>
`以下是示例代码:`
```java
##解释器模式(Interpreter) GoF这样定义: >给定一个语言,定义它的文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中的句子。
`以下是示例代码:` ```java ```°

ThreadPoolExecutor 源码分析

/*
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/

/*
*
* Written by Doug Lea with assistance from members of JCP JSR-166
* Expert Group and released to the public domain, as explained at
* http://creativecommons.org/publicdomain/zero/1.0/
*/

package java.util.concurrent;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.*;

/**
*一个ExecutorService执行每个被提交入到线程池中的任务,通过Executors工厂方法进行配置。
*线程池处理两种不同的问题:通过减少每个任务调用的开销、提供边界和资源管理,包括线程,
*任务集合的执行,从而改进了执行大量异步任务时的性能问题。ThreadPoolExcecutor也维护着一
*些统计数据,如已完成任务的数目。
*面对一个提供了许多可调用参数和可扩展性的hooks.程序员通常比较喜欢用Executors的工厂方法。
*如Executors.newCachedThreadPool(无限大小的线程池,自动线程回收)、Executors.newFixedThreadPool
*(固定大小的线程池)、Executors.newSingleThreadExecutor(单个后台线程),为最常用的场
*景进行预配置。或者,使用这个类进行手动配置实现同样的效果的线程池,
*
* 核心和最大的线程池
*
* ThreadPoolExecutor会根据线程池的大小配置corePoolSize和maximumPoolSize来自动调整池的大小,
*可以通过getPoolSize查看池的大小。
*
* When a new task is submitted in method {@link #execute(Runnable)},
* and fewer than corePoolSize threads are running, a new thread is
* created to handle the request, even if other worker threads are
* idle. If there are more than corePoolSize but less than
* maximumPoolSize threads running, a new thread will be created only
* if the queue is full. By setting corePoolSize and maximumPoolSize
* the same, you create a fixed-size thread pool. By setting
* maximumPoolSize to an essentially unbounded value such as {@code
* Integer.MAX_VALUE}, you allow the pool to accommodate an arbitrary
* number of concurrent tasks. Most typically, core and maximum pool
* sizes are set only upon construction, but they may also be changed
* dynamically using {@link #setCorePoolSize} and {@link
* #setMaximumPoolSize}. </dd>
*
* <dt>On-demand construction</dt>
*
* <dd>By default, even core threads are initially created and
* started only when new tasks arrive, but this can be overridden
* dynamically using method {@link #prestartCoreThread} or {@link
* #prestartAllCoreThreads}. You probably want to prestart threads if
* you construct the pool with a non-empty queue. </dd>
*
* <dt>Creating new threads</dt>
*
* <dd>New threads are created using a {@link ThreadFactory}. If not
* otherwise specified, a {@link Executors#defaultThreadFactory} is
* used, that creates threads to all be in the same {@link
* ThreadGroup} and with the same {@code NORM_PRIORITY} priority and
* non-daemon status. By supplying a different ThreadFactory, you can
* alter the thread's name, thread group, priority, daemon status,
* etc. If a {@code ThreadFactory} fails to create a thread when asked
* by returning null from {@code newThread}, the executor will
* continue, but might not be able to execute any tasks. Threads
* should possess the "modifyThread" {@code RuntimePermission}. If
* worker threads or other threads using the pool do not possess this
* permission, service may be degraded: configuration changes may not
* take effect in a timely manner, and a shutdown pool may remain in a
* state in which termination is possible but not completed.</dd>
*
* <dt>Keep-alive times</dt>
*
* <dd>If the pool currently has more than corePoolSize threads,
* excess threads will be terminated if they have been idle for more
* than the keepAliveTime (see {@link #getKeepAliveTime(TimeUnit)}).
* This provides a means of reducing resource consumption when the
* pool is not being actively used. If the pool becomes more active
* later, new threads will be constructed. This parameter can also be
* changed dynamically using method {@link #setKeepAliveTime(long,
* TimeUnit)}. Using a value of {@code Long.MAX_VALUE} {@link
* TimeUnit#NANOSECONDS} effectively disables idle threads from ever
* terminating prior to shut down. By default, the keep-alive policy
* applies only when there are more than corePoolSize threads. But
* method {@link #allowCoreThreadTimeOut(boolean)} can be used to
* apply this time-out policy to core threads as well, so long as the
* keepAliveTime value is non-zero. </dd>
*
* <dt>Queuing</dt>
*
* <dd>Any {@link BlockingQueue} may be used to transfer and hold
* submitted tasks. The use of this queue interacts with pool sizing:
*
* <ul>
*
* <li> If fewer than corePoolSize threads are running, the Executor
* always prefers adding a new thread
* rather than queuing.</li>
*
* <li> If corePoolSize or more threads are running, the Executor
* always prefers queuing a request rather than adding a new
* thread.</li>
*
* <li> If a request cannot be queued, a new thread is created unless
* this would exceed maximumPoolSize, in which case, the task will be
* rejected.</li>
*
* </ul>
*
* There are three general strategies for queuing:
* <ol>
*
* <li> <em> Direct handoffs.</em> A good default choice for a work
* queue is a {@link SynchronousQueue} that hands off tasks to threads
* without otherwise holding them. Here, an attempt to queue a task
* will fail if no threads are immediately available to run it, so a
* new thread will be constructed. This policy avoids lockups when
* handling sets of requests that might have internal dependencies.
* Direct handoffs generally require unbounded maximumPoolSizes to
* avoid rejection of new submitted tasks. This in turn admits the
* possibility of unbounded thread growth when commands continue to
* arrive on average faster than they can be processed. </li>
*
* <li><em> Unbounded queues.</em> Using an unbounded queue (for
* example a {@link LinkedBlockingQueue} without a predefined
* capacity) will cause new tasks to wait in the queue when all
* corePoolSize threads are busy. Thus, no more than corePoolSize
* threads will ever be created. (And the value of the maximumPoolSize
* therefore doesn't have any effect.) This may be appropriate when
* each task is completely independent of others, so tasks cannot
* affect each others execution; for example, in a web page server.
* While this style of queuing can be useful in smoothing out
* transient bursts of requests, it admits the possibility of
* unbounded work queue growth when commands continue to arrive on
* average faster than they can be processed. </li>
*
* <li><em>Bounded queues.</em> A bounded queue (for example, an
* {@link ArrayBlockingQueue}) helps prevent resource exhaustion when
* used with finite maximumPoolSizes, but can be more difficult to
* tune and control. Queue sizes and maximum pool sizes may be traded
* off for each other: Using large queues and small pools minimizes
* CPU usage, OS resources, and context-switching overhead, but can
* lead to artificially low throughput. If tasks frequently block (for
* example if they are I/O bound), a system may be able to schedule
* time for more threads than you otherwise allow. Use of small queues
* generally requires larger pool sizes, which keeps CPUs busier but
* may encounter unacceptable scheduling overhead, which also
* decreases throughput. </li>
*
* </ol>
*
* </dd>
*
* <dt>Rejected tasks</dt>
*
* <dd>New tasks submitted in method {@link #execute(Runnable)} will be
* <em>rejected</em> when the Executor has been shut down, and also when
* the Executor uses finite bounds for both maximum threads and work queue
* capacity, and is saturated. In either case, the {@code execute} method
* invokes the {@link
* RejectedExecutionHandler#rejectedExecution(Runnable, ThreadPoolExecutor)}
* method of its {@link RejectedExecutionHandler}. Four predefined handler
* policies are provided:
*
* <ol>
*
* <li> In the default {@link ThreadPoolExecutor.AbortPolicy}, the
* handler throws a runtime {@link RejectedExecutionException} upon
* rejection. </li>
*
* <li> In {@link ThreadPoolExecutor.CallerRunsPolicy}, the thread
* that invokes {@code execute} itself runs the task. This provides a
* simple feedback control mechanism that will slow down the rate that
* new tasks are submitted. </li>
*
* <li> In {@link ThreadPoolExecutor.DiscardPolicy}, a task that
* cannot be executed is simply dropped. </li>
*
* <li>In {@link ThreadPoolExecutor.DiscardOldestPolicy}, if the
* executor is not shut down, the task at the head of the work queue
* is dropped, and then execution is retried (which can fail again,
* causing this to be repeated.) </li>
*
* </ol>
*
* It is possible to define and use other kinds of {@link
* RejectedExecutionHandler} classes. Doing so requires some care
* especially when policies are designed to work only under particular
* capacity or queuing policies. </dd>
*
* <dt>Hook methods</dt>
*
* <dd>This class provides {@code protected} overridable
* {@link #beforeExecute(Thread, Runnable)} and
* {@link #afterExecute(Runnable, Throwable)} methods that are called
* before and after execution of each task. These can be used to
* manipulate the execution environment; for example, reinitializing
* ThreadLocals, gathering statistics, or adding log entries.
* Additionally, method {@link #terminated} can be overridden to perform
* any special processing that needs to be done once the Executor has
* fully terminated.
*
* <p>If hook or callback methods throw exceptions, internal worker
* threads may in turn fail and abruptly terminate.</dd>
*
* <dt>Queue maintenance</dt>
*
* <dd>Method {@link #getQueue()} allows access to the work queue
* for purposes of monitoring and debugging. Use of this method for
* any other purpose is strongly discouraged. Two supplied methods,
* {@link #remove(Runnable)} and {@link #purge} are available to
* assist in storage reclamation when large numbers of queued tasks
* become cancelled.</dd>
*
* <dt>Finalization</dt>
*
* <dd>A pool that is no longer referenced in a program <em>AND</em>
* has no remaining threads will be {@code shutdown} automatically. If
* you would like to ensure that unreferenced pools are reclaimed even
* if users forget to call {@link #shutdown}, then you must arrange
* that unused threads eventually die, by setting appropriate
* keep-alive times, using a lower bound of zero core threads and/or
* setting {@link #allowCoreThreadTimeOut(boolean)}. </dd>
*
* </dl>
*
* <p><b>Extension example</b>. Most extensions of this class
* override one or more of the protected hook methods. For example,
* here is a subclass that adds a simple pause/resume feature:
*
* <pre> {@code
* class PausableThreadPoolExecutor extends ThreadPoolExecutor {
* private boolean isPaused;
* private ReentrantLock pauseLock = new ReentrantLock();
* private Condition unpaused = pauseLock.newCondition();
*
* public PausableThreadPoolExecutor(...) { super(...); }
*
* protected void beforeExecute(Thread t, Runnable r) {
* super.beforeExecute(t, r);
* pauseLock.lock();
* try {
* while (isPaused) unpaused.await();
* } catch (InterruptedException ie) {
* t.interrupt();
* } finally {
* pauseLock.unlock();
* }
* }
*
* public void pause() {
* pauseLock.lock();
* try {
* isPaused = true;
* } finally {
* pauseLock.unlock();
* }
* }
*
* public void resume() {
* pauseLock.lock();
* try {
* isPaused = false;
* unpaused.signalAll();
* } finally {
* pauseLock.unlock();
* }
* }
* }}</pre>
*
* @since 1.5
* @author Doug Lea
*/
public class ThreadPoolExecutor extends AbstractExecutorService {
/**
* The main pool control state, ctl, is an atomic integer packing
* two conceptual fields
* workerCount, indicating the effective number of threads
* runState, indicating whether running, shutting down etc
*
* In order to pack them into one int, we limit workerCount to
* (2^29)-1 (about 500 million) threads rather than (2^31)-1 (2
* billion) otherwise representable. If this is ever an issue in
* the future, the variable can be changed to be an AtomicLong,
* and the shift/mask constants below adjusted. But until the need
* arises, this code is a bit faster and simpler using an int.
*
* The workerCount is the number of workers that have been
* permitted to start and not permitted to stop. The value may be
* transiently different from the actual number of live threads,
* for example when a ThreadFactory fails to create a thread when
* asked, and when exiting threads are still performing
* bookkeeping before terminating. The user-visible pool size is
* reported as the current size of the workers set.
*
* The runState provides the main lifecycle control, taking on values:
*
* RUNNING: Accept new tasks and process queued tasks
* SHUTDOWN: Don't accept new tasks, but process queued tasks
* STOP: Don't accept new tasks, don't process queued tasks,
* and interrupt in-progress tasks
* TIDYING: All tasks have terminated, workerCount is zero,
* the thread transitioning to state TIDYING
* will run the terminated() hook method
* TERMINATED: terminated() has completed
*
* The numerical order among these values matters, to allow
* ordered comparisons. The runState monotonically increases over
* time, but need not hit each state. The transitions are:
*
* RUNNING -> SHUTDOWN
* On invocation of shutdown(), perhaps implicitly in finalize()
* (RUNNING or SHUTDOWN) -> STOP
* On invocation of shutdownNow()
* SHUTDOWN -> TIDYING
* When both queue and pool are empty
* STOP -> TIDYING
* When pool is empty
* TIDYING -> TERMINATED
* When the terminated() hook method has completed
*
* Threads waiting in awaitTermination() will return when the
* state reaches TERMINATED.
*
* Detecting the transition from SHUTDOWN to TIDYING is less
* straightforward than you'd like because the queue may become
* empty after non-empty and vice versa during SHUTDOWN state, but
* we can only terminate if, after seeing that it is empty, we see
* that workerCount is 0 (which sometimes entails a recheck -- see
* below).
*/
private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
private static final int COUNT_BITS = Integer.SIZE - 3;
private static final int CAPACITY = (1 << COUNT_BITS) - 1;

// runState is stored in the high-order bits
private static final int RUNNING = -1 << COUNT_BITS;
private static final int SHUTDOWN = 0 << COUNT_BITS;
private static final int STOP = 1 << COUNT_BITS;
private static final int TIDYING = 2 << COUNT_BITS;
private static final int TERMINATED = 3 << COUNT_BITS;

// Packing and unpacking ctl
private static int runStateOf(int c) { return c & ~CAPACITY; }
private static int workerCountOf(int c) { return c & CAPACITY; }
private static int ctlOf(int rs, int wc) { return rs | wc; }

/*
* Bit field accessors that don't require unpacking ctl.
* These depend on the bit layout and on workerCount being never negative.
*/

private static boolean runStateLessThan(int c, int s) {
return c < s;
}

private static boolean runStateAtLeast(int c, int s) {
return c >= s;
}

private static boolean isRunning(int c) {
return c < SHUTDOWN;
}

/**
* Attempts to CAS-increment the workerCount field of ctl.
*/
private boolean compareAndIncrementWorkerCount(int expect) {
return ctl.compareAndSet(expect, expect + 1);
}

/**
* Attempts to CAS-decrement the workerCount field of ctl.
*/
private boolean compareAndDecrementWorkerCount(int expect) {
return ctl.compareAndSet(expect, expect - 1);
}

/**
* Decrements the workerCount field of ctl. This is called only on
* abrupt termination of a thread (see processWorkerExit). Other
* decrements are performed within getTask.
*/
private void decrementWorkerCount() {
do {} while (! compareAndDecrementWorkerCount(ctl.get()));
}

/**
* The queue used for holding tasks and handing off to worker
* threads. We do not require that workQueue.poll() returning
* null necessarily means that workQueue.isEmpty(), so rely
* solely on isEmpty to see if the queue is empty (which we must
* do for example when deciding whether to transition from
* SHUTDOWN to TIDYING). This accommodates special-purpose
* queues such as DelayQueues for which poll() is allowed to
* return null even if it may later return non-null when delays
* expire.
*/
private final BlockingQueue<Runnable> workQueue;

/**
* Lock held on access to workers set and related bookkeeping.
* While we could use a concurrent set of some sort, it turns out
* to be generally preferable to use a lock. Among the reasons is
* that this serializes interruptIdleWorkers, which avoids
* unnecessary interrupt storms, especially during shutdown.
* Otherwise exiting threads would concurrently interrupt those
* that have not yet interrupted. It also simplifies some of the
* associated statistics bookkeeping of largestPoolSize etc. We
* also hold mainLock on shutdown and shutdownNow, for the sake of
* ensuring workers set is stable while separately checking
* permission to interrupt and actually interrupting.
*/
private final ReentrantLock mainLock = new ReentrantLock();

/**
* Set containing all worker threads in pool. Accessed only when
* holding mainLock.
*/
private final HashSet<Worker> workers = new HashSet<Worker>();

/**
* Wait condition to support awaitTermination
*/
private final Condition termination = mainLock.newCondition();

/**
* Tracks largest attained pool size. Accessed only under
* mainLock.
*/
private int largestPoolSize;

/**
* Counter for completed tasks. Updated only on termination of
* worker threads. Accessed only under mainLock.
*/
private long completedTaskCount;

/*
* All user control parameters are declared as volatiles so that
* ongoing actions are based on freshest values, but without need
* for locking, since no internal invariants depend on them
* changing synchronously with respect to other actions.
*/

/**
* Factory for new threads. All threads are created using this
* factory (via method addWorker). All callers must be prepared
* for addWorker to fail, which may reflect a system or user's
* policy limiting the number of threads. Even though it is not
* treated as an error, failure to create threads may result in
* new tasks being rejected or existing ones remaining stuck in
* the queue.
*
* We go further and preserve pool invariants even in the face of
* errors such as OutOfMemoryError, that might be thrown while
* trying to create threads. Such errors are rather common due to
* the need to allocate a native stack in Thread.start, and users
* will want to perform clean pool shutdown to clean up. There
* will likely be enough memory available for the cleanup code to
* complete without encountering yet another OutOfMemoryError.
*/
private volatile ThreadFactory threadFactory;

/**
* Handler called when saturated or shutdown in execute.
*/
private volatile RejectedExecutionHandler handler;

/**
* Timeout in nanoseconds for idle threads waiting for work.
* Threads use this timeout when there are more than corePoolSize
* present or if allowCoreThreadTimeOut. Otherwise they wait
* forever for new work.
*/
private volatile long keepAliveTime;

/**
* If false (default), core threads stay alive even when idle.
* If true, core threads use keepAliveTime to time out waiting
* for work.
*/
private volatile boolean allowCoreThreadTimeOut;

/**
* Core pool size is the minimum number of workers to keep alive
* (and not allow to time out etc) unless allowCoreThreadTimeOut
* is set, in which case the minimum is zero.
*/
private volatile int corePoolSize;

/**
* Maximum pool size. Note that the actual maximum is internally
* bounded by CAPACITY.
*/
private volatile int maximumPoolSize;

/**
* The default rejected execution handler
*/
private static final RejectedExecutionHandler defaultHandler =
new AbortPolicy();

/**
* Permission required for callers of shutdown and shutdownNow.
* We additionally require (see checkShutdownAccess) that callers
* have permission to actually interrupt threads in the worker set
* (as governed by Thread.interrupt, which relies on
* ThreadGroup.checkAccess, which in turn relies on
* SecurityManager.checkAccess). Shutdowns are attempted only if
* these checks pass.
*
* All actual invocations of Thread.interrupt (see
* interruptIdleWorkers and interruptWorkers) ignore
* SecurityExceptions, meaning that the attempted interrupts
* silently fail. In the case of shutdown, they should not fail
* unless the SecurityManager has inconsistent policies, sometimes
* allowing access to a thread and sometimes not. In such cases,
* failure to actually interrupt threads may disable or delay full
* termination. Other uses of interruptIdleWorkers are advisory,
* and failure to actually interrupt will merely delay response to
* configuration changes so is not handled exceptionally.
*/
private static final RuntimePermission shutdownPerm =
new RuntimePermission("modifyThread");

/**
* Class Worker mainly maintains interrupt control state for
* threads running tasks, along with other minor bookkeeping.
* This class opportunistically extends AbstractQueuedSynchronizer
* to simplify acquiring and releasing a lock surrounding each
* task execution. This protects against interrupts that are
* intended to wake up a worker thread waiting for a task from
* instead interrupting a task being run. We implement a simple
* non-reentrant mutual exclusion lock rather than use
* ReentrantLock because we do not want worker tasks to be able to
* reacquire the lock when they invoke pool control methods like
* setCorePoolSize. Additionally, to suppress interrupts until
* the thread actually starts running tasks, we initialize lock
* state to a negative value, and clear it upon start (in
* runWorker).
*/
private final class Worker
extends AbstractQueuedSynchronizer
implements Runnable
{
/**
* This class will never be serialized, but we provide a
* serialVersionUID to suppress a javac warning.
*/
private static final long serialVersionUID = 6138294804551838833L;

/** Thread this worker is running in. Null if factory fails. */
final Thread thread;
/** Initial task to run. Possibly null. */
Runnable firstTask;
/** Per-thread task counter */
volatile long completedTasks;

/**
* Creates with given first task and thread from ThreadFactory.
* @param firstTask the first task (null if none)
*/
Worker(Runnable firstTask) {
setState(-1); // inhibit interrupts until runWorker
this.firstTask = firstTask;
this.thread = getThreadFactory().newThread(this);
}

/** Delegates main run loop to outer runWorker */
public void run() {
runWorker(this);
}

// Lock methods
//
// The value 0 represents the unlocked state.
// The value 1 represents the locked state.

protected boolean isHeldExclusively() {
return getState() != 0;
}

protected boolean tryAcquire(int unused) {
if (compareAndSetState(0, 1)) {
setExclusiveOwnerThread(Thread.currentThread());
return true;
}
return false;
}

protected boolean tryRelease(int unused) {
setExclusiveOwnerThread(null);
setState(0);
return true;
}

public void lock() { acquire(1); }
public boolean tryLock() { return tryAcquire(1); }
public void unlock() { release(1); }
public boolean isLocked() { return isHeldExclusively(); }

void interruptIfStarted() {
Thread t;
if (getState() >= 0 && (t = thread) != null && !t.isInterrupted()) {
try {
t.interrupt();
} catch (SecurityException ignore) {
}
}
}
}

/*
* Methods for setting control state
*/

/**
* Transitions runState to given target, or leaves it alone if
* already at least the given target.
*
* @param targetState the desired state, either SHUTDOWN or STOP
* (but not TIDYING or TERMINATED -- use tryTerminate for that)
*/
private void advanceRunState(int targetState) {
for (;;) {
int c = ctl.get();
if (runStateAtLeast(c, targetState) ||
ctl.compareAndSet(c, ctlOf(targetState, workerCountOf(c))))
break;
}
}

/**
* Transitions to TERMINATED state if either (SHUTDOWN and pool
* and queue empty) or (STOP and pool empty). If otherwise
* eligible to terminate but workerCount is nonzero, interrupts an
* idle worker to ensure that shutdown signals propagate. This
* method must be called following any action that might make
* termination possible -- reducing worker count or removing tasks
* from the queue during shutdown. The method is non-private to
* allow access from ScheduledThreadPoolExecutor.
*/
final void tryTerminate() {
for (;;) {
int c = ctl.get();
if (isRunning(c) ||
runStateAtLeast(c, TIDYING) ||
(runStateOf(c) == SHUTDOWN && ! workQueue.isEmpty()))
return;
if (workerCountOf(c) != 0) { // Eligible to terminate
interruptIdleWorkers(ONLY_ONE);
return;
}

final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
if (ctl.compareAndSet(c, ctlOf(TIDYING, 0))) {
try {
terminated();
} finally {
ctl.set(ctlOf(TERMINATED, 0));
termination.signalAll();
}
return;
}
} finally {
mainLock.unlock();
}
// else retry on failed CAS
}
}

/*
* Methods for controlling interrupts to worker threads.
*/

/**
* If there is a security manager, makes sure caller has
* permission to shut down threads in general (see shutdownPerm).
* If this passes, additionally makes sure the caller is allowed
* to interrupt each worker thread. This might not be true even if
* first check passed, if the SecurityManager treats some threads
* specially.
*/
private void checkShutdownAccess() {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkPermission(shutdownPerm);
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
for (Worker w : workers)
security.checkAccess(w.thread);
} finally {
mainLock.unlock();
}
}
}

/**
* Interrupts all threads, even if active. Ignores SecurityExceptions
* (in which case some threads may remain uninterrupted).
*/
private void interruptWorkers() {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
for (Worker w : workers)
w.interruptIfStarted();
} finally {
mainLock.unlock();
}
}

/**
* Interrupts threads that might be waiting for tasks (as
* indicated by not being locked) so they can check for
* termination or configuration changes. Ignores
* SecurityExceptions (in which case some threads may remain
* uninterrupted).
*
* @param onlyOne If true, interrupt at most one worker. This is
* called only from tryTerminate when termination is otherwise
* enabled but there are still other workers. In this case, at
* most one waiting worker is interrupted to propagate shutdown
* signals in case all threads are currently waiting.
* Interrupting any arbitrary thread ensures that newly arriving
* workers since shutdown began will also eventually exit.
* To guarantee eventual termination, it suffices to always
* interrupt only one idle worker, but shutdown() interrupts all
* idle workers so that redundant workers exit promptly, not
* waiting for a straggler task to finish.
*/
private void interruptIdleWorkers(boolean onlyOne) {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
for (Worker w : workers) {
Thread t = w.thread;
if (!t.isInterrupted() && w.tryLock()) {
try {
t.interrupt();
} catch (SecurityException ignore) {
} finally {
w.unlock();
}
}
if (onlyOne)
break;
}
} finally {
mainLock.unlock();
}
}

/**
* Common form of interruptIdleWorkers, to avoid having to
* remember what the boolean argument means.
*/
private void interruptIdleWorkers() {
interruptIdleWorkers(false);
}

private static final boolean ONLY_ONE = true;

/*
* Misc utilities, most of which are also exported to
* ScheduledThreadPoolExecutor
*/

/**
* Invokes the rejected execution handler for the given command.
* Package-protected for use by ScheduledThreadPoolExecutor.
*/
final void reject(Runnable command) {
handler.rejectedExecution(command, this);
}

/**
* Performs any further cleanup following run state transition on
* invocation of shutdown. A no-op here, but used by
* ScheduledThreadPoolExecutor to cancel delayed tasks.
*/
void onShutdown() {
}

/**
* State check needed by ScheduledThreadPoolExecutor to
* enable running tasks during shutdown.
*
* @param shutdownOK true if should return true if SHUTDOWN
*/
final boolean isRunningOrShutdown(boolean shutdownOK) {
int rs = runStateOf(ctl.get());
return rs == RUNNING || (rs == SHUTDOWN && shutdownOK);
}

/**
* Drains the task queue into a new list, normally using
* drainTo. But if the queue is a DelayQueue or any other kind of
* queue for which poll or drainTo may fail to remove some
* elements, it deletes them one by one.
*/
private List<Runnable> drainQueue() {
BlockingQueue<Runnable> q = workQueue;
ArrayList<Runnable> taskList = new ArrayList<Runnable>();
q.drainTo(taskList);
if (!q.isEmpty()) {
for (Runnable r : q.toArray(new Runnable[0])) {
if (q.remove(r))
taskList.add(r);
}
}
return taskList;
}

/*
* Methods for creating, running and cleaning up after workers
*/

/**
* Checks if a new worker can be added with respect to current
* pool state and the given bound (either core or maximum). If so,
* the worker count is adjusted accordingly, and, if possible, a
* new worker is created and started, running firstTask as its
* first task. This method returns false if the pool is stopped or
* eligible to shut down. It also returns false if the thread
* factory fails to create a thread when asked. If the thread
* creation fails, either due to the thread factory returning
* null, or due to an exception (typically OutOfMemoryError in
* Thread.start()), we roll back cleanly.
*
* @param firstTask the task the new thread should run first (or
* null if none). Workers are created with an initial first task
* (in method execute()) to bypass queuing when there are fewer
* than corePoolSize threads (in which case we always start one),
* or when the queue is full (in which case we must bypass queue).
* Initially idle threads are usually created via
* prestartCoreThread or to replace other dying workers.
*
* @param core if true use corePoolSize as bound, else
* maximumPoolSize. (A boolean indicator is used here rather than a
* value to ensure reads of fresh values after checking other pool
* state).
* @return true if successful
*/
private boolean addWorker(Runnable firstTask, boolean core) {
retry:
for (;;) {
int c = ctl.get();
int rs = runStateOf(c);

// Check if queue empty only if necessary.
if (rs >= SHUTDOWN &&
! (rs == SHUTDOWN &&
firstTask == null &&
! workQueue.isEmpty()))
return false;

for (;;) {
int wc = workerCountOf(c);
if (wc >= CAPACITY ||
wc >= (core ? corePoolSize : maximumPoolSize))
return false;
if (compareAndIncrementWorkerCount(c))
break retry;
c = ctl.get(); // Re-read ctl
if (runStateOf(c) != rs)
continue retry;
// else CAS failed due to workerCount change; retry inner loop
}
}

boolean workerStarted = false;
boolean workerAdded = false;
Worker w = null;
try {
w = new Worker(firstTask);
final Thread t = w.thread;
if (t != null) {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
// Recheck while holding lock.
// Back out on ThreadFactory failure or if
// shut down before lock acquired.
int rs = runStateOf(ctl.get());

if (rs < SHUTDOWN ||
(rs == SHUTDOWN && firstTask == null)) {
if (t.isAlive()) // precheck that t is startable
throw new IllegalThreadStateException();
workers.add(w);
int s = workers.size();
if (s > largestPoolSize)
largestPoolSize = s;
workerAdded = true;
}
} finally {
mainLock.unlock();
}
if (workerAdded) {
t.start();
workerStarted = true;
}
}
} finally {
if (! workerStarted)
addWorkerFailed(w);
}
return workerStarted;
}

/**
* Rolls back the worker thread creation.
* - removes worker from workers, if present
* - decrements worker count
* - rechecks for termination, in case the existence of this
* worker was holding up termination
*/
private void addWorkerFailed(Worker w) {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
if (w != null)
workers.remove(w);
decrementWorkerCount();
tryTerminate();
} finally {
mainLock.unlock();
}
}

/**
* Performs cleanup and bookkeeping for a dying worker. Called
* only from worker threads. Unless completedAbruptly is set,
* assumes that workerCount has already been adjusted to account
* for exit. This method removes thread from worker set, and
* possibly terminates the pool or replaces the worker if either
* it exited due to user task exception or if fewer than
* corePoolSize workers are running or queue is non-empty but
* there are no workers.
*
* @param w the worker
* @param completedAbruptly if the worker died due to user exception
*/
private void processWorkerExit(Worker w, boolean completedAbruptly) {
if (completedAbruptly) // If abrupt, then workerCount wasn't adjusted
decrementWorkerCount();

final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
completedTaskCount += w.completedTasks;
workers.remove(w);
} finally {
mainLock.unlock();
}

tryTerminate();

int c = ctl.get();
if (runStateLessThan(c, STOP)) {
if (!completedAbruptly) {
int min = allowCoreThreadTimeOut ? 0 : corePoolSize;
if (min == 0 && ! workQueue.isEmpty())
min = 1;
if (workerCountOf(c) >= min)
return; // replacement not needed
}
addWorker(null, false);
}
}

/**
* Performs blocking or timed wait for a task, depending on
* current configuration settings, or returns null if this worker
* must exit because of any of:
* 1. There are more than maximumPoolSize workers (due to
* a call to setMaximumPoolSize).
* 2. The pool is stopped.
* 3. The pool is shutdown and the queue is empty.
* 4. This worker timed out waiting for a task, and timed-out
* workers are subject to termination (that is,
* {@code allowCoreThreadTimeOut || workerCount > corePoolSize})
* both before and after the timed wait, and if the queue is
* non-empty, this worker is not the last thread in the pool.
*
* @return task, or null if the worker must exit, in which case
* workerCount is decremented
*/
private Runnable getTask() {
boolean timedOut = false; // Did the last poll() time out?

for (;;) {
int c = ctl.get();
int rs = runStateOf(c);

// Check if queue empty only if necessary.
if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) {
decrementWorkerCount();
return null;
}

int wc = workerCountOf(c);

// Are workers subject to culling?
boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;

if ((wc > maximumPoolSize || (timed && timedOut))
&& (wc > 1 || workQueue.isEmpty())) {
if (compareAndDecrementWorkerCount(c))
return null;
continue;
}

try {
Runnable r = timed ?
workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
workQueue.take();
if (r != null)
return r;
timedOut = true;
} catch (InterruptedException retry) {
timedOut = false;
}
}
}

/**
* Main worker run loop. Repeatedly gets tasks from queue and
* executes them, while coping with a number of issues:
*
* 1. We may start out with an initial task, in which case we
* don't need to get the first one. Otherwise, as long as pool is
* running, we get tasks from getTask. If it returns null then the
* worker exits due to changed pool state or configuration
* parameters. Other exits result from exception throws in
* external code, in which case completedAbruptly holds, which
* usually leads processWorkerExit to replace this thread.
*
* 2. Before running any task, the lock is acquired to prevent
* other pool interrupts while the task is executing, and then we
* ensure that unless pool is stopping, this thread does not have
* its interrupt set.
*
* 3. Each task run is preceded by a call to beforeExecute, which
* might throw an exception, in which case we cause thread to die
* (breaking loop with completedAbruptly true) without processing
* the task.
*
* 4. Assuming beforeExecute completes normally, we run the task,
* gathering any of its thrown exceptions to send to afterExecute.
* We separately handle RuntimeException, Error (both of which the
* specs guarantee that we trap) and arbitrary Throwables.
* Because we cannot rethrow Throwables within Runnable.run, we
* wrap them within Errors on the way out (to the thread's
* UncaughtExceptionHandler). Any thrown exception also
* conservatively causes thread to die.
*
* 5. After task.run completes, we call afterExecute, which may
* also throw an exception, which will also cause thread to
* die. According to JLS Sec 14.20, this exception is the one that
* will be in effect even if task.run throws.
*
* The net effect of the exception mechanics is that afterExecute
* and the thread's UncaughtExceptionHandler have as accurate
* information as we can provide about any problems encountered by
* user code.
*
* @param w the worker
*/
final void runWorker(Worker w) {
Thread wt = Thread.currentThread();
Runnable task = w.firstTask;
w.firstTask = null;
w.unlock(); // allow interrupts
boolean completedAbruptly = true;
try {
while (task != null || (task = getTask()) != null) {
w.lock();
// If pool is stopping, ensure thread is interrupted;
// if not, ensure thread is not interrupted. This
// requires a recheck in second case to deal with
// shutdownNow race while clearing interrupt
if ((runStateAtLeast(ctl.get(), STOP) ||
(Thread.interrupted() &&
runStateAtLeast(ctl.get(), STOP))) &&
!wt.isInterrupted())
wt.interrupt();
try {
beforeExecute(wt, task);
Throwable thrown = null;
try {
task.run();
} catch (RuntimeException x) {
thrown = x; throw x;
} catch (Error x) {
thrown = x; throw x;
} catch (Throwable x) {
thrown = x; throw new Error(x);
} finally {
afterExecute(task, thrown);
}
} finally {
task = null;
w.completedTasks++;
w.unlock();
}
}
completedAbruptly = false;
} finally {
processWorkerExit(w, completedAbruptly);
}
}

// Public constructors and methods

/**
* Creates a new {@code ThreadPoolExecutor} with the given initial
* parameters and default thread factory and rejected execution handler.
* It may be more convenient to use one of the {@link Executors} factory
* methods instead of this general purpose constructor.
*
* @param corePoolSize the number of threads to keep in the pool, even
* if they are idle, unless {@code allowCoreThreadTimeOut} is set
* @param maximumPoolSize the maximum number of threads to allow in the
* pool
* @param keepAliveTime when the number of threads is greater than
* the core, this is the maximum time that excess idle threads
* will wait for new tasks before terminating.
* @param unit the time unit for the {@code keepAliveTime} argument
* @param workQueue the queue to use for holding tasks before they are
* executed. This queue will hold only the {@code Runnable}
* tasks submitted by the {@code execute} method.
* @throws IllegalArgumentException if one of the following holds:<br>
* {@code corePoolSize < 0}<br>
* {@code keepAliveTime < 0}<br>
* {@code maximumPoolSize <= 0}<br>
* {@code maximumPoolSize < corePoolSize}
* @throws NullPointerException if {@code workQueue} is null
*/
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), defaultHandler);
}

/**
* Creates a new {@code ThreadPoolExecutor} with the given initial
* parameters and default rejected execution handler.
*
* @param corePoolSize the number of threads to keep in the pool, even
* if they are idle, unless {@code allowCoreThreadTimeOut} is set
* @param maximumPoolSize the maximum number of threads to allow in the
* pool
* @param keepAliveTime when the number of threads is greater than
* the core, this is the maximum time that excess idle threads
* will wait for new tasks before terminating.
* @param unit the time unit for the {@code keepAliveTime} argument
* @param workQueue the queue to use for holding tasks before they are
* executed. This queue will hold only the {@code Runnable}
* tasks submitted by the {@code execute} method.
* @param threadFactory the factory to use when the executor
* creates a new thread
* @throws IllegalArgumentException if one of the following holds:<br>
* {@code corePoolSize < 0}<br>
* {@code keepAliveTime < 0}<br>
* {@code maximumPoolSize <= 0}<br>
* {@code maximumPoolSize < corePoolSize}
* @throws NullPointerException if {@code workQueue}
* or {@code threadFactory} is null
*/
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
threadFactory, defaultHandler);
}

/**
* Creates a new {@code ThreadPoolExecutor} with the given initial
* parameters and default thread factory.
*
* @param corePoolSize the number of threads to keep in the pool, even
* if they are idle, unless {@code allowCoreThreadTimeOut} is set
* @param maximumPoolSize the maximum number of threads to allow in the
* pool
* @param keepAliveTime when the number of threads is greater than
* the core, this is the maximum time that excess idle threads
* will wait for new tasks before terminating.
* @param unit the time unit for the {@code keepAliveTime} argument
* @param workQueue the queue to use for holding tasks before they are
* executed. This queue will hold only the {@code Runnable}
* tasks submitted by the {@code execute} method.
* @param handler the handler to use when execution is blocked
* because the thread bounds and queue capacities are reached
* @throws IllegalArgumentException if one of the following holds:<br>
* {@code corePoolSize < 0}<br>
* {@code keepAliveTime < 0}<br>
* {@code maximumPoolSize <= 0}<br>
* {@code maximumPoolSize < corePoolSize}
* @throws NullPointerException if {@code workQueue}
* or {@code handler} is null
*/
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
RejectedExecutionHandler handler) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), handler);
}

/**
* Creates a new {@code ThreadPoolExecutor} with the given initial
* parameters.
*
* @param corePoolSize the number of threads to keep in the pool, even
* if they are idle, unless {@code allowCoreThreadTimeOut} is set
* @param maximumPoolSize the maximum number of threads to allow in the
* pool
* @param keepAliveTime when the number of threads is greater than
* the core, this is the maximum time that excess idle threads
* will wait for new tasks before terminating.
* @param unit the time unit for the {@code keepAliveTime} argument
* @param workQueue the queue to use for holding tasks before they are
* executed. This queue will hold only the {@code Runnable}
* tasks submitted by the {@code execute} method.
* @param threadFactory the factory to use when the executor
* creates a new thread
* @param handler the handler to use when execution is blocked
* because the thread bounds and queue capacities are reached
* @throws IllegalArgumentException if one of the following holds:<br>
* {@code corePoolSize < 0}<br>
* {@code keepAliveTime < 0}<br>
* {@code maximumPoolSize <= 0}<br>
* {@code maximumPoolSize < corePoolSize}
* @throws NullPointerException if {@code workQueue}
* or {@code threadFactory} or {@code handler} is null
*/
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {
if (corePoolSize < 0 ||
maximumPoolSize <= 0 ||
maximumPoolSize < corePoolSize ||
keepAliveTime < 0)
throw new IllegalArgumentException();
if (workQueue == null || threadFactory == null || handler == null)
throw new NullPointerException();
this.corePoolSize = corePoolSize;
this.maximumPoolSize = maximumPoolSize;
this.workQueue = workQueue;
this.keepAliveTime = unit.toNanos(keepAliveTime);
this.threadFactory = threadFactory;
this.handler = handler;
}

/**
* Executes the given task sometime in the future. The task
* may execute in a new thread or in an existing pooled thread.
*
* If the task cannot be submitted for execution, either because this
* executor has been shutdown or because its capacity has been reached,
* the task is handled by the current {@code RejectedExecutionHandler}.
*
* @param command the task to execute
* @throws RejectedExecutionException at discretion of
* {@code RejectedExecutionHandler}, if the task
* cannot be accepted for execution
* @throws NullPointerException if {@code command} is null
*/
public void execute(Runnable command) {
if (command == null)
throw new NullPointerException();
/*
* Proceed in 3 steps:
*
* 1. If fewer than corePoolSize threads are running, try to
* start a new thread with the given command as its first
* task. The call to addWorker atomically checks runState and
* workerCount, and so prevents false alarms that would add
* threads when it shouldn't, by returning false.
*
* 2. If a task can be successfully queued, then we still need
* to double-check whether we should have added a thread
* (because existing ones died since last checking) or that
* the pool shut down since entry into this method. So we
* recheck state and if necessary roll back the enqueuing if
* stopped, or start a new thread if there are none.
*
* 3. If we cannot queue task, then we try to add a new
* thread. If it fails, we know we are shut down or saturated
* and so reject the task.
*/
int c = ctl.get();
if (workerCountOf(c) < corePoolSize) {
if (addWorker(command, true))
return;
c = ctl.get();
}
if (isRunning(c) && workQueue.offer(command)) {
int recheck = ctl.get();
if (! isRunning(recheck) && remove(command))
reject(command);
else if (workerCountOf(recheck) == 0)
addWorker(null, false);
}
else if (!addWorker(command, false))
reject(command);
}

/**
* Initiates an orderly shutdown in which previously submitted
* tasks are executed, but no new tasks will be accepted.
* Invocation has no additional effect if already shut down.
*
* <p>This method does not wait for previously submitted tasks to
* complete execution. Use {@link #awaitTermination awaitTermination}
* to do that.
*
* @throws SecurityException {@inheritDoc}
*/
public void shutdown() {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
checkShutdownAccess();
advanceRunState(SHUTDOWN);
interruptIdleWorkers();
onShutdown(); // hook for ScheduledThreadPoolExecutor
} finally {
mainLock.unlock();
}
tryTerminate();
}

/**
* Attempts to stop all actively executing tasks, halts the
* processing of waiting tasks, and returns a list of the tasks
* that were awaiting execution. These tasks are drained (removed)
* from the task queue upon return from this method.
*
* <p>This method does not wait for actively executing tasks to
* terminate. Use {@link #awaitTermination awaitTermination} to
* do that.
*
* <p>There are no guarantees beyond best-effort attempts to stop
* processing actively executing tasks. This implementation
* cancels tasks via {@link Thread#interrupt}, so any task that
* fails to respond to interrupts may never terminate.
*
* @throws SecurityException {@inheritDoc}
*/
public List<Runnable> shutdownNow() {
List<Runnable> tasks;
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
checkShutdownAccess();
advanceRunState(STOP);
interruptWorkers();
tasks = drainQueue();
} finally {
mainLock.unlock();
}
tryTerminate();
return tasks;
}

public boolean isShutdown() {
return ! isRunning(ctl.get());
}

/**
* Returns true if this executor is in the process of terminating
* after {@link #shutdown} or {@link #shutdownNow} but has not
* completely terminated. This method may be useful for
* debugging. A return of {@code true} reported a sufficient
* period after shutdown may indicate that submitted tasks have
* ignored or suppressed interruption, causing this executor not
* to properly terminate.
*
* @return {@code true} if terminating but not yet terminated
*/
public boolean isTerminating() {
int c = ctl.get();
return ! isRunning(c) && runStateLessThan(c, TERMINATED);
}

public boolean isTerminated() {
return runStateAtLeast(ctl.get(), TERMINATED);
}

public boolean awaitTermination(long timeout, TimeUnit unit)
throws InterruptedException {
long nanos = unit.toNanos(timeout);
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
for (;;) {
if (runStateAtLeast(ctl.get(), TERMINATED))
return true;
if (nanos <= 0)
return false;
nanos = termination.awaitNanos(nanos);
}
} finally {
mainLock.unlock();
}
}

/**
* Invokes {@code shutdown} when this executor is no longer
* referenced and it has no threads.
*/
protected void finalize() {
shutdown();
}

/**
* Sets the thread factory used to create new threads.
*
* @param threadFactory the new thread factory
* @throws NullPointerException if threadFactory is null
* @see #getThreadFactory
*/
public void setThreadFactory(ThreadFactory threadFactory) {
if (threadFactory == null)
throw new NullPointerException();
this.threadFactory = threadFactory;
}

/**
* Returns the thread factory used to create new threads.
*
* @return the current thread factory
* @see #setThreadFactory(ThreadFactory)
*/
public ThreadFactory getThreadFactory() {
return threadFactory;
}

/**
* Sets a new handler for unexecutable tasks.
*
* @param handler the new handler
* @throws NullPointerException if handler is null
* @see #getRejectedExecutionHandler
*/
public void setRejectedExecutionHandler(RejectedExecutionHandler handler) {
if (handler == null)
throw new NullPointerException();
this.handler = handler;
}

/**
* Returns the current handler for unexecutable tasks.
*
* @return the current handler
* @see #setRejectedExecutionHandler(RejectedExecutionHandler)
*/
public RejectedExecutionHandler getRejectedExecutionHandler() {
return handler;
}

/**
* Sets the core number of threads. This overrides any value set
* in the constructor. If the new value is smaller than the
* current value, excess existing threads will be terminated when
* they next become idle. If larger, new threads will, if needed,
* be started to execute any queued tasks.
*
* @param corePoolSize the new core size
* @throws IllegalArgumentException if {@code corePoolSize < 0}
* @see #getCorePoolSize
*/
public void setCorePoolSize(int corePoolSize) {
if (corePoolSize < 0)
throw new IllegalArgumentException();
int delta = corePoolSize - this.corePoolSize;
this.corePoolSize = corePoolSize;
if (workerCountOf(ctl.get()) > corePoolSize)
interruptIdleWorkers();
else if (delta > 0) {
// We don't really know how many new threads are "needed".
// As a heuristic, prestart enough new workers (up to new
// core size) to handle the current number of tasks in
// queue, but stop if queue becomes empty while doing so.
int k = Math.min(delta, workQueue.size());
while (k-- > 0 && addWorker(null, true)) {
if (workQueue.isEmpty())
break;
}
}
}

/**
* Returns the core number of threads.
*
* @return the core number of threads
* @see #setCorePoolSize
*/
public int getCorePoolSize() {
return corePoolSize;
}

/**
* Starts a core thread, causing it to idly wait for work. This
* overrides the default policy of starting core threads only when
* new tasks are executed. This method will return {@code false}
* if all core threads have already been started.
*
* @return {@code true} if a thread was started
*/
public boolean prestartCoreThread() {
return workerCountOf(ctl.get()) < corePoolSize &&
addWorker(null, true);
}

/**
* Same as prestartCoreThread except arranges that at least one
* thread is started even if corePoolSize is 0.
*/
void ensurePrestart() {
int wc = workerCountOf(ctl.get());
if (wc < corePoolSize)
addWorker(null, true);
else if (wc == 0)
addWorker(null, false);
}

/**
* Starts all core threads, causing them to idly wait for work. This
* overrides the default policy of starting core threads only when
* new tasks are executed.
*
* @return the number of threads started
*/
public int prestartAllCoreThreads() {
int n = 0;
while (addWorker(null, true))
++n;
return n;
}

/**
* Returns true if this pool allows core threads to time out and
* terminate if no tasks arrive within the keepAlive time, being
* replaced if needed when new tasks arrive. When true, the same
* keep-alive policy applying to non-core threads applies also to
* core threads. When false (the default), core threads are never
* terminated due to lack of incoming tasks.
*
* @return {@code true} if core threads are allowed to time out,
* else {@code false}
*
* @since 1.6
*/
public boolean allowsCoreThreadTimeOut() {
return allowCoreThreadTimeOut;
}

/**
* Sets the policy governing whether core threads may time out and
* terminate if no tasks arrive within the keep-alive time, being
* replaced if needed when new tasks arrive. When false, core
* threads are never terminated due to lack of incoming
* tasks. When true, the same keep-alive policy applying to
* non-core threads applies also to core threads. To avoid
* continual thread replacement, the keep-alive time must be
* greater than zero when setting {@code true}. This method
* should in general be called before the pool is actively used.
*
* @param value {@code true} if should time out, else {@code false}
* @throws IllegalArgumentException if value is {@code true}
* and the current keep-alive time is not greater than zero
*
* @since 1.6
*/
public void allowCoreThreadTimeOut(boolean value) {
if (value && keepAliveTime <= 0)
throw new IllegalArgumentException("Core threads must have nonzero keep alive times");
if (value != allowCoreThreadTimeOut) {
allowCoreThreadTimeOut = value;
if (value)
interruptIdleWorkers();
}
}

/**
* Sets the maximum allowed number of threads. This overrides any
* value set in the constructor. If the new value is smaller than
* the current value, excess existing threads will be
* terminated when they next become idle.
*
* @param maximumPoolSize the new maximum
* @throws IllegalArgumentException if the new maximum is
* less than or equal to zero, or
* less than the {@linkplain #getCorePoolSize core pool size}
* @see #getMaximumPoolSize
*/
public void setMaximumPoolSize(int maximumPoolSize) {
if (maximumPoolSize <= 0 || maximumPoolSize < corePoolSize)
throw new IllegalArgumentException();
this.maximumPoolSize = maximumPoolSize;
if (workerCountOf(ctl.get()) > maximumPoolSize)
interruptIdleWorkers();
}

/**
* Returns the maximum allowed number of threads.
*
* @return the maximum allowed number of threads
* @see #setMaximumPoolSize
*/
public int getMaximumPoolSize() {
return maximumPoolSize;
}

/**
* Sets the time limit for which threads may remain idle before
* being terminated. If there are more than the core number of
* threads currently in the pool, after waiting this amount of
* time without processing a task, excess threads will be
* terminated. This overrides any value set in the constructor.
*
* @param time the time to wait. A time value of zero will cause
* excess threads to terminate immediately after executing tasks.
* @param unit the time unit of the {@code time} argument
* @throws IllegalArgumentException if {@code time} less than zero or
* if {@code time} is zero and {@code allowsCoreThreadTimeOut}
* @see #getKeepAliveTime(TimeUnit)
*/
public void setKeepAliveTime(long time, TimeUnit unit) {
if (time < 0)
throw new IllegalArgumentException();
if (time == 0 && allowsCoreThreadTimeOut())
throw new IllegalArgumentException("Core threads must have nonzero keep alive times");
long keepAliveTime = unit.toNanos(time);
long delta = keepAliveTime - this.keepAliveTime;
this.keepAliveTime = keepAliveTime;
if (delta < 0)
interruptIdleWorkers();
}

/**
* Returns the thread keep-alive time, which is the amount of time
* that threads in excess of the core pool size may remain
* idle before being terminated.
*
* @param unit the desired time unit of the result
* @return the time limit
* @see #setKeepAliveTime(long, TimeUnit)
*/
public long getKeepAliveTime(TimeUnit unit) {
return unit.convert(keepAliveTime, TimeUnit.NANOSECONDS);
}

/* User-level queue utilities */

/**
* Returns the task queue used by this executor. Access to the
* task queue is intended primarily for debugging and monitoring.
* This queue may be in active use. Retrieving the task queue
* does not prevent queued tasks from executing.
*
* @return the task queue
*/
public BlockingQueue<Runnable> getQueue() {
return workQueue;
}

/**
* Removes this task from the executor's internal queue if it is
* present, thus causing it not to be run if it has not already
* started.
*
* <p>This method may be useful as one part of a cancellation
* scheme. It may fail to remove tasks that have been converted
* into other forms before being placed on the internal queue. For
* example, a task entered using {@code submit} might be
* converted into a form that maintains {@code Future} status.
* However, in such cases, method {@link #purge} may be used to
* remove those Futures that have been cancelled.
*
* @param task the task to remove
* @return {@code true} if the task was removed
*/
public boolean remove(Runnable task) {
boolean removed = workQueue.remove(task);
tryTerminate(); // In case SHUTDOWN and now empty
return removed;
}

/**
* Tries to remove from the work queue all {@link Future}
* tasks that have been cancelled. This method can be useful as a
* storage reclamation operation, that has no other impact on
* functionality. Cancelled tasks are never executed, but may
* accumulate in work queues until worker threads can actively
* remove them. Invoking this method instead tries to remove them now.
* However, this method may fail to remove tasks in
* the presence of interference by other threads.
*/
public void purge() {
final BlockingQueue<Runnable> q = workQueue;
try {
Iterator<Runnable> it = q.iterator();
while (it.hasNext()) {
Runnable r = it.next();
if (r instanceof Future<?> && ((Future<?>)r).isCancelled())
it.remove();
}
} catch (ConcurrentModificationException fallThrough) {
// Take slow path if we encounter interference during traversal.
// Make copy for traversal and call remove for cancelled entries.
// The slow path is more likely to be O(N*N).
for (Object r : q.toArray())
if (r instanceof Future<?> && ((Future<?>)r).isCancelled())
q.remove(r);
}

tryTerminate(); // In case SHUTDOWN and now empty
}

/* Statistics */

/**
* Returns the current number of threads in the pool.
*
* @return the number of threads
*/
public int getPoolSize() {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
// Remove rare and surprising possibility of
// isTerminated() && getPoolSize() > 0
return runStateAtLeast(ctl.get(), TIDYING) ? 0
: workers.size();
} finally {
mainLock.unlock();
}
}

/**
* Returns the approximate number of threads that are actively
* executing tasks.
*
* @return the number of threads
*/
public int getActiveCount() {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
int n = 0;
for (Worker w : workers)
if (w.isLocked())
++n;
return n;
} finally {
mainLock.unlock();
}
}

/**
* Returns the largest number of threads that have ever
* simultaneously been in the pool.
*
* @return the number of threads
*/
public int getLargestPoolSize() {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
return largestPoolSize;
} finally {
mainLock.unlock();
}
}

/**
* Returns the approximate total number of tasks that have ever been
* scheduled for execution. Because the states of tasks and
* threads may change dynamically during computation, the returned
* value is only an approximation.
*
* @return the number of tasks
*/
public long getTaskCount() {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
long n = completedTaskCount;
for (Worker w : workers) {
n += w.completedTasks;
if (w.isLocked())
++n;
}
return n + workQueue.size();
} finally {
mainLock.unlock();
}
}

/**
* Returns the approximate total number of tasks that have
* completed execution. Because the states of tasks and threads
* may change dynamically during computation, the returned value
* is only an approximation, but one that does not ever decrease
* across successive calls.
*
* @return the number of tasks
*/
public long getCompletedTaskCount() {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
long n = completedTaskCount;
for (Worker w : workers)
n += w.completedTasks;
return n;
} finally {
mainLock.unlock();
}
}

/**
* Returns a string identifying this pool, as well as its state,
* including indications of run state and estimated worker and
* task counts.
*
* @return a string identifying this pool, as well as its state
*/
public String toString() {
long ncompleted;
int nworkers, nactive;
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
ncompleted = completedTaskCount;
nactive = 0;
nworkers = workers.size();
for (Worker w : workers) {
ncompleted += w.completedTasks;
if (w.isLocked())
++nactive;
}
} finally {
mainLock.unlock();
}
int c = ctl.get();
String rs = (runStateLessThan(c, SHUTDOWN) ? "Running" :
(runStateAtLeast(c, TERMINATED) ? "Terminated" :
"Shutting down"));
return super.toString() +
"[" + rs +
", pool size = " + nworkers +
", active threads = " + nactive +
", queued tasks = " + workQueue.size() +
", completed tasks = " + ncompleted +
"]";
}

/* Extension hooks */

/**
* Method invoked prior to executing the given Runnable in the
* given thread. This method is invoked by thread {@code t} that
* will execute task {@code r}, and may be used to re-initialize
* ThreadLocals, or to perform logging.
*
* <p>This implementation does nothing, but may be customized in
* subclasses. Note: To properly nest multiple overridings, subclasses
* should generally invoke {@code super.beforeExecute} at the end of
* this method.
*
* @param t the thread that will run task {@code r}
* @param r the task that will be executed
*/
protected void beforeExecute(Thread t, Runnable r) { }

/**
* Method invoked upon completion of execution of the given Runnable.
* This method is invoked by the thread that executed the task. If
* non-null, the Throwable is the uncaught {@code RuntimeException}
* or {@code Error} that caused execution to terminate abruptly.
*
* <p>This implementation does nothing, but may be customized in
* subclasses. Note: To properly nest multiple overridings, subclasses
* should generally invoke {@code super.afterExecute} at the
* beginning of this method.
*
* <p><b>Note:</b> When actions are enclosed in tasks (such as
* {@link FutureTask}) either explicitly or via methods such as
* {@code submit}, these task objects catch and maintain
* computational exceptions, and so they do not cause abrupt
* termination, and the internal exceptions are <em>not</em>
* passed to this method. If you would like to trap both kinds of
* failures in this method, you can further probe for such cases,
* as in this sample subclass that prints either the direct cause
* or the underlying exception if a task has been aborted:
*
* <pre> {@code
* class ExtendedExecutor extends ThreadPoolExecutor {
* // ...
* protected void afterExecute(Runnable r, Throwable t) {
* super.afterExecute(r, t);
* if (t == null && r instanceof Future<?>) {
* try {
* Object result = ((Future<?>) r).get();
* } catch (CancellationException ce) {
* t = ce;
* } catch (ExecutionException ee) {
* t = ee.getCause();
* } catch (InterruptedException ie) {
* Thread.currentThread().interrupt(); // ignore/reset
* }
* }
* if (t != null)
* System.out.println(t);
* }
* }}</pre>
*
* @param r the runnable that has completed
* @param t the exception that caused termination, or null if
* execution completed normally
*/
protected void afterExecute(Runnable r, Throwable t) { }

/**
* Method invoked when the Executor has terminated. Default
* implementation does nothing. Note: To properly nest multiple
* overridings, subclasses should generally invoke
* {@code super.terminated} within this method.
*/
protected void terminated() { }

/* Predefined RejectedExecutionHandlers */

/**
* A handler for rejected tasks that runs the rejected task
* directly in the calling thread of the {@code execute} method,
* unless the executor has been shut down, in which case the task
* is discarded.
*/
public static class CallerRunsPolicy implements RejectedExecutionHandler {
/**
* Creates a {@code CallerRunsPolicy}.
*/
public CallerRunsPolicy() { }

/**
* Executes task r in the caller's thread, unless the executor
* has been shut down, in which case the task is discarded.
*
* @param r the runnable task requested to be executed
* @param e the executor attempting to execute this task
*/
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
if (!e.isShutdown()) {
r.run();
}
}
}

/**
* A handler for rejected tasks that throws a
* {@code RejectedExecutionException}.
*/
public static class AbortPolicy implements RejectedExecutionHandler {
/**
* Creates an {@code AbortPolicy}.
*/
public AbortPolicy() { }

/**
* Always throws RejectedExecutionException.
*
* @param r the runnable task requested to be executed
* @param e the executor attempting to execute this task
* @throws RejectedExecutionException always
*/
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
throw new RejectedExecutionException("Task " + r.toString() +
" rejected from " +
e.toString());
}
}

/**
* A handler for rejected tasks that silently discards the
* rejected task.
*/
public static class DiscardPolicy implements RejectedExecutionHandler {
/**
* Creates a {@code DiscardPolicy}.
*/
public DiscardPolicy() { }

/**
* Does nothing, which has the effect of discarding task r.
*
* @param r the runnable task requested to be executed
* @param e the executor attempting to execute this task
*/
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
}
}

/**
* A handler for rejected tasks that discards the oldest unhandled
* request and then retries {@code execute}, unless the executor
* is shut down, in which case the task is discarded.
*/
public static class DiscardOldestPolicy implements RejectedExecutionHandler {
/**
* Creates a {@code DiscardOldestPolicy} for the given executor.
*/
public DiscardOldestPolicy() { }

/**
* Obtains and ignores the next task that the executor
* would otherwise execute, if one is immediately available,
* and then retries execution of task r, unless the executor
* is shut down, in which case task r is instead discarded.
*
* @param r the runnable task requested to be executed
* @param e the executor attempting to execute this task
*/
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
if (!e.isShutdown()) {
e.getQueue().poll();
e.execute(r);
}
}
}
}

设计模式分类

平时工作代码进行重构时也会涉及到设计模式,另外在看一些开源框架时也会涉及到很多的设计模式。只是平时没有太全面的了解,最近面试时有同事问汲到这里,所以在这里整理以备将来随时查看。
这里我举一个最容易理解的例子来解释每种设计模式
首先看一下设计模式的分类及关系

它们之间的关系如图:

##创建型模式
这六个模式都是与创建对象相关的

  • 简单工厂模式(Simple Factory);
  • 工厂方法模式(Factory Method);
  • 抽象工厂模式(Abstract Factory);
  • 创建者模式(Builder);
  • 原型模式(Prototype);
  • 单例模式(Singleton);

##结构型模式

创建对象后,对象与对象之间的依赖关系,设计好了会为后续代码的维护带来很大的方便。

  • 外观模式(Facade);
  • 适配器模式(Adapter);
  • 代理模式(Proxy);
  • 装饰模式(Decorator);
  • 桥模式(Bridge);
  • 组合模式(Composite);
  • 享元模式(Flyweight)

##行为型模式

对象的创建和结构定义好后,就是他们的行为的设计了。
模板方法模式(Template Method);

  • 观察者模式(Observer);
  • 状态模式(State);
  • 策略模式(Strategy);
  • 职责链模式(Chain of Responsibility);
  • 命令模式(Command);
  • 访问者模式(Visitor);
  • 调停者模式(Mediator);
  • 备忘录模式(Memento);
  • 迭代器模式(Iterator);
  • 解释器模式(Interpreter)