`
chhj_292
  • 浏览: 36834 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

生产消费模式应用之-使用中断队列实现的日志记录器

阅读更多

包含三个功能类(1~3)以及一个测试类(4):

  1. AbstractLogger
  2. LoggerConsumption
  3. LoggerProduction
  4. LoggerTester

相 信看类名大家已经知道了这是个生产-消费的应用。
非常冒昧的把代码加入了com.taobao.log.* 这个package,尽管这只是个测试。

 

以下是代码区域:

 

package com.taobao.log;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

/**
 * 使用了生产消费模式,并使用了中断队列的日志基类。
 * 
 * @author <a href="mailto:haojun.chenghj@163.com"><b>chenghaojun</b></a>,wangwang:tbjaver(Taobao site)
 * @since 
 * @see LoggerProduction
 * @see LoggerConsumption
 * @version $Id:AbstractLogger.java 2010-3-18 $
 */

public abstract class AbstractLogger implements Runnable {

	/** 初始日志队列大小 */
	private static final int				ITEMS_SIZE			= 100;

	/** 关闭日志标识 */
	protected static final String			SHUTDOWN_REQ		= "SHUTDOWN";

	/** 使用中断队列的日志池,用于追加或者获取数据 */
	private static BlockingQueue<String>	loggerPool			= null;

	private volatile boolean				loggerShuttingDown	= false;
	private volatile boolean				loggerTerminated	= false;

	static {
		loggerPool = new ArrayBlockingQueue<String>(ITEMS_SIZE);
	}

	/** 只允许子类获取的日志池 */
	protected BlockingQueue<String> getLoggerPool() {
		return loggerPool;
	}

	/**
	 * 定义方法模板,强制让子类实现此方法。
	 */
	public abstract void run();

	/**================================================*/
	public boolean isLoggerShuttingDown() {
		return loggerShuttingDown;
	}

	public void setLoggerShuttingDown(boolean loggerShuttingDown) {
		this.loggerShuttingDown = loggerShuttingDown;
	}

	public boolean isLoggerTerminated() {
		return loggerTerminated;
	}

	public void setLoggerTerminated(boolean loggerTerminated) {
		this.loggerTerminated = loggerTerminated;
	}
}

 

 

package com.taobao.log;

/**
 * 生产消费模式中的消费者,不断的从队列中获取并输出日志。
 * 
 * @author <a href="mailto:haojun.chenghj@163.com"><b>chenghaojun</b></a>,wangwang:tbjaver(Taobao site)
 * @since 
 * @see 
 * @version $Id:LoggerConsumption.java 2010-3-18 $
 */

public class LoggerConsumption extends AbstractLogger {
	private static final LoggerConsumption	loggerConsumption	= new LoggerConsumption();

	public static LoggerConsumption getInstance() {
		return loggerConsumption;
	}

	private LoggerConsumption() {
	}

	@Override
	public void run() {
		try {
			String log = null;
			while (!(log = getLoggerPool().take())
					.equalsIgnoreCase(SHUTDOWN_REQ)) {
				System.out.println(log);
			}
		} catch (InterruptedException e) {
			e.printStackTrace();
		} finally {
			setLoggerTerminated(true);
		}
	}
}
 

 

package com.taobao.log;

/**
 * 生产消费模式中的生产者,不断的往日志队列中加入新的日志
 * @author <a href="mailto:haojun.chenghj@163.com"><b>chenghaojun</b></a>,wangwang:tbjaver(Taobao site)
 * @since 
 * @see 
 * @version $Id:LoggerThread.java 2010-3-18 $
 */

public class LoggerProduction extends AbstractLogger {

	private static final LoggerProduction	loggerProduction	= new LoggerProduction();

	public static LoggerProduction getInstance() {
		return loggerProduction;
	}

	private LoggerProduction() {
	}

	@Override
	public void run() {
		for (;;) {
			String log = "sorry, I come to fuck you!";
			log(log);
		}
	}

	public void log(String str) {
		if (isLoggerShuttingDown() || isLoggerTerminated())
			return;
		try {
			getLoggerPool().put(str);
		} catch (InterruptedException e) {
			Thread.currentThread().interrupt();
			throw new RuntimeException("程序发生意料之外的中断,错误消息:" + e.getMessage());
		}
	}

	public void shutDown() throws InterruptedException {
		setLoggerShuttingDown(true);
		getLoggerPool().put(SHUTDOWN_REQ);
	}

}
 

 

package com.taobao.log;

/**
 * just a tester
 * @author <a href="mailto:haojun.chenghj@163.com"><b>chenghaojun</b></a>,wangwang:tbjaver(Taobao site)
 * @since 
 * @see 
 * @version $Id:LoggerMain.java 2010-3-18 $
 */

public class LoggerTester {
	public static void main(String[] args) {
		Thread production = new Thread(LoggerProduction.getInstance());
		Thread consumption = new Thread(LoggerConsumption.getInstance());
		production.start();
		consumption.start();
	}
}
 
0
0
分享到:
评论

相关推荐

    (重要)AIX command 使用总结.txt

    首先确认系统中已经安装了“bos.content_list”文件集(fileset), 如果没有安装, 请使用smitty installp进行安装. 运行which_fileset命令, 根据文件查找对应的文件集. 例如: #which_fileset iostat /usr/bin/...

    IIS6.0 IIS,互联网信息服务

    IIS有默认的端口设置,只要稍有计算机知识的人都会记得这些端口的,要破解的话就十分的方便,所以尽量不要使用21这个默认端口号,并启用日志,以便FTP服务出现异常时检查。 [编辑本段]对IIS服务的远程管理  三、对...

    hivemind:基于Procfile的应用程序的流程管理器

    Procfile是一种简单格式,用于指定应用程序提供的进程类型(例如Web应用程序服务器,后台队列进程,前端构建器)以及运行这些进程的命令。 它可以极大地简化开发人员的流程管理,并被诸如Heroku和Deis之类的流行...

    overmind:基于Procfile的应用程序和tmux的进程管理器

    Procfile是一种简单格式,用于指定应用程序提供的进程类型(例如Web应用程序服务器,后台队列进程,前端构建器)以及运行这些进程的命令。 它可以显着简化开发人员的流程管理,并被Heroku和Deis等流行的托管平台所...

    Linux系统故障诊断与排除--James Kirkland

    4.2.1 将日志记录到单独磁盘 86 4.2.2 确定文件系统请求的I/O大小 88 4.2.3 用小块I/O传输加载文件系统 88 4.2.4 利用文件系统的关键优势 91 4.2.5 Linux和Windows性能以及调整扇区对齐 92 4.2.6 使用...

    Windows 系统错误代码简单分析

     0133 对于包含已连接驱动器的驱动器,不能使用 JOIN 或 SUBST 命令。  0134 试图在已经连接的驱动器上使用 JOIN 或 SUBST 命令。  0135 试图在已经替换的驱动器上使用 JOIN 或 SUBST 命令。  0136 系统...

    Oracle 主要配置文件介绍

    保护数据考虑的 尤其在 CAMS 双机应用模式下 能够保证数据的一致性 具体的修改操作可参考 Linux与 Oracle 安装手册 初始化参数文件是一个包含实例配置参数的文本文件 这些参数被设置为特 定的值 用于...

    UNIX环境高级编程(第二版中文).pdf

    10.5 中断的系统调用 207 10.6 可再入函数 209 10.7 SIGCLD语义 211 10.8 可靠信号术语和语义 213 10.9 kill和raise函数 213 10.10 alarm和pause函数 214 10.11 信号集 219 10.12 sigprocmask 函数 220 10.13 ...

    精通websphere MQ

    队列管理器 (Queue Manager).............................................................. 23 1.2.4 通道 (Channel)................................................................................... 24...

    JAVA核心知识点整理(有效)

    1. 目录 1. 2. 目录 .........................................................................................................................................................1 JVM ........................

Global site tag (gtag.js) - Google Analytics