前面介绍过spring的taskExecutor,今天介绍一个jdk里处理多线程的方法
一、spring的配置文件(注入bean)
<bean id="cmsClickButtonMng" class="com.xxx.manager.main.impl.CmsClickButtonMngImpl"/>
二、线程类CustomerButton.java
import java.util.concurrent.BlockingQueue;
import nl.bitwalker.useragentutils.UserAgent;
import org.apache.commons.lang.StringUtils;
import org.springframework.web.context.ContextLoader;
import org.springframework.web.context.WebApplicationContext;
import com.xxxx.cms.entity.main.CmsClickButton;
import com.xxxx.cms.manager.main.CmsClickButtonMng;
import com.xxxx.common.util.UserAgentUtils;
@SuppressWarnings("rawtypes")
public class ConsumerButton implements Runnable{
public static boolean running = false;
protected WebApplicationContext ctx;
private CmsClickButtonMng cmsClickButtonMng;//要处理的类
protected BlockingQueue queue = null;
protected static int i = 0; public ConsumerButton(BlockingQueue queue) {
this.queue = queue;
} public void run() {
try {
System.out.println("queue大小为:"+ queue.size());
while(!queue.isEmpty()){
CmsClickButton cb = (CmsClickButton) queue.take();
if(cb != null){
record(cb);
}
}
ConsumerButton.running = false;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/**业务*/
public void record(CmsClickButton cb){
try {
if(cb != null){
if(StringUtils.isNotBlank(cb.getAgent())){
String agent = cb.getAgent();
String customerModel = UserAgentUtils.getCustomerModel(agent);//手机型号
cb.setCustomerModel(customerModel);
UserAgent userAgent = UserAgent.parseUserAgentString(agent);
if(userAgent != null){
String browserName = String.valueOf(userAgent.getBrowser().getName());//浏览器类型
String operatingSystem = String.valueOf(userAgent.getOperatingSystem().getName());//操作系统类型
String browserVersion =String.valueOf(userAgent.getBrowserVersion());//浏览器版本
boolean isMobileDevice = userAgent.getOperatingSystem().isMobileDevice();//是否是移动设备
cb.setBrowserName(browserName);
cb.setBrowserVersion(browserVersion);
cb.setIsMobileDevice(isMobileDevice);
cb.setOperatingSystem(operatingSystem);
}
}
WebApplicationContext wac = ContextLoader.getCurrentWebApplicationContext();
cmsClickButtonMng = (CmsClickButtonMng) wac.getBean("cmsClickButtonMng");
cmsClickButtonMng.saveCb(cb);
ConsumerButton.i++;
System.out.println("finish ..."+ConsumerButton.i);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
三、Producer.java
import java.util.concurrent.BlockingQueue;
import com.gmiao.cms.entity.main.CmsClickButton;
import com.gmiao.cms.entity.main.CmsTrafficPage;
@SuppressWarnings("rawtypes")
public class Producer implements Runnable {
protected BlockingQueue queue = null;
protected CmsTrafficPage tp = null; //产品一
protected CmsClickButton cb = null; //产品二
public Producer(BlockingQueue queue,CmsTrafficPage tp) {
this.queue = queue;
this.tp = tp;
}
public Producer(BlockingQueue queue,CmsClickButton cb) {
this.queue = queue;
this.cb = cb;
}
@SuppressWarnings("unchecked")
public void run() {
try {
if(tp != null){
queue.put(tp);
}else if(cb != null){
queue.put(cb);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
四、springmvc
/**
* 参数指队列的最大容量
*/
public static BlockingQueue queue = new ArrayBlockingQueue(10000);
@RequestMapping(value="/save.jspf")
public void save(String pid,String openId,String pageName,HttpServletRequest request,HttpServletResponse response){
try {
//如果项目id或 页面名称为空,则不作记录
if(StringUtils.isBlank(pid) || StringUtils.isBlank(pageName)){
ajaxErrorToJson(response, null, "项目id或页面名称不能为空!");
return ;
}
CmsTrafficPage tp = new CmsTrafficPage();
tp.setPid(pid);
tp.setDate(new Date());
tp.setStayTime(0l);
tp.setIp(RequestUtils.getIpAddr(request));//用户ip地址
tp.setPageName(pageName);
tp.setPageUrl(request.getHeader("Referer"));//发起请求的页面链接
tp.setSessionId(request.getSession().getId());//用户sessionId
String agent = request.getHeader("user-agent");//客户端信息
if(StringUtils.isNotBlank(agent)){
tp.setAgent(agent);
}
BlockingQueue queue = TrafficPageAct.queue;//所在的action或controller
Producer producer = new Producer(queue,tp);
new Thread(producer).start();
if(!Consumer.running){
Consumer consumer = new Consumer(queue);
new Thread(consumer).start();
Consumer.running = true;
}
} catch (Exception e) {
log.error("记录页面的访问出错了!",e);
ajaxErrorToJson(response, null, "记录页面访问出错了!");
return ;
}
}
我这里只是项目代码中使用BlockQueue,要了解或学习可以查看下面一位网页的文章http://wsmajunfeng.iteye.com/blog/1629354或查看jdk文档


  

160801、BlockingQueue处理多线程的更多相关文章

  1. 阅读ArrayBlockingQueue源码了解如何利用锁实现BlockingQueue

    BlockingQueue是多线程里面一个非常重要的数据结构.在面试的时候,也常会被问到怎么实现BlockingQueue.本篇根据Java7里ArrayBlockingQueue的源码,简单介绍一下 ...

  2. Java Nio 笔记

    网上的很多关于NIO的资料是不正确的,nio 支持阻塞和非阻塞模式 关于读写状态切换 在读写状态切换的情况下是不能使用regedit 方法注册,而应该使用以下方式进行 selectionKey.int ...

  3. Mudo C++网络库第三章学习笔记

    多线程服务器的适用场合与常用编程模型 进程间通信与线程同步; 以最简单规范的方式开发功能正确.线程安全的多线程程序; 多线程服务器是指运行在linux操作系统上的独占式网络应用程序; 不考虑分布式存储 ...

  4. 多线程编程-工具篇-BlockingQueue

    在新增的Concurrent包中,BlockingQueue很好的解决了多线程中,如何高效安全"传输"数据的问题.通过这些高效并且线程安全的队列类,为我们快速搭建高质量的多线程程序 ...

  5. Java多线程15:Queue、BlockingQueue以及利用BlockingQueue实现生产者/消费者模型

    Queue是什么 队列,是一种数据结构.除了优先级队列和LIFO队列外,队列都是以FIFO(先进先出)的方式对各个元素进行排序的.无论使用哪种排序方式,队列的头都是调用remove()或poll()移 ...

  6. JAVA多线程之间共享数据BlockingQueue介绍

    在JAVA的Concurrent包中,BlockingQueue很好的解决了多线程中,如何高效安全“传输”数据的问题.通过这些高效并且线程安全的队列类,为我们快速搭建高质量的多线程程序带来极大的便利. ...

  7. Java多线程-工具篇-BlockingQueue

    前言: 在新增的Concurrent包中,BlockingQueue很好的解决了多线程中,如何高效安全“传输”数据的问题.通过这些高效并且线程安全的队列 类,为我们快速搭建高质量的多线程程序带来极大的 ...

  8. Java多线程-工具篇-BlockingQueue(转)

    前言: 在新增的Concurrent包中,BlockingQueue很好的解决了多线程中,如何高效安全“传输”数据的问题.通过这些高效并且线程安全的队列 类,为我们快速搭建高质量的多线程程序带来极大的 ...

  9. 多线程学习之BlockingQueue

    前言: 在新增的Concurrent包中,BlockingQueue很好的解决了多线程中,如何高效安全“传输”数据的问题.通过这些高效并且线程安全的队列 类,为我们快速搭建高质量的多线程程序带来极大的 ...

随机推荐

  1. git团队协作流程

    创建项目,在github上增加一个repository,在要提交的工程目录下打开git bash,执行git init 命令,用于初始化,可使用git status 查看git状态,然后使用git a ...

  2. spring in action第一章小结1

    1 spring基本理念是简化java开发. 使用以下4个策略简化java开发 1) 基于POJO的轻量级和最小侵入性编程 2)通过使用DI和AOP实现松耦合 3)基于切面和惯例进行声明式编程 4)通 ...

  3. zookeeper(五):Zookeeper中的Access Control(ACL)

    概述 传统的文件系统中,ACL分为两个维度,一个是属组,一个是权限,子目录/文件默认继承父目录的ACL.而在Zookeeper中,node的ACL是没有继承关系的,是独立控制的. Zookeeper的 ...

  4. 深入Activity

    此刻,你应该静下心来,在阅读中思考.在思考中进步,读完本篇文章的你一定会有不一样的收获,请让我们共同进步! 核心内容 1.Activity数据交换 2.Activity中的任务栈 3.Activity ...

  5. 多线程-ThreadPoolExecutor

    线程池 线程池是可以控制线程创建.释放.并通过某种策略尝试复用线程去执行任务的一种管理框架,从而实现线程资源与任务之间的一种平衡. 类图 Executor Executor是最基本的执行接口:“执行者 ...

  6. django的html模板中获取字典的值

    在django的html模板中获取字典中的值应当直接使用 字典.[key] 的方式 {% for i in lists %} <li id="{{i.id}}" class ...

  7. .net访问Oracle数据库

    使用System.Data.OracleClient访问Oracle数据库时报错 尝试加载 Oracle 客户端库时引发 BadImageFormatException.如果在安装 32 位 Orac ...

  8. 线上定位GC内存泄露问题

    原因:Java中存在内存泄露,就是因为对象无用却可达. 举个例子: 在这个例子中,我们循环申请Object对象,并将所申请的对象放入一个Vector中,如果我们仅仅释放引用本身,那么Vector仍然引 ...

  9. spring-core依赖jar包

  10. Linux上安装Nginx及常用命令

    一.Linux安装软件常用方法 1.rpm(或pkg)安装,类似于Windows安装程序,是预编译好的程序. 1)使用的是通用参数编译,配置参数不是最佳 2)可控制性不强,比如对程序特定组件的定制性安 ...