前面介绍过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. C# Interview Questions:C#-English Questions

    This is a list of questions I have gathered from other sources and created myself over a period of t ...

  2. unity, Global和Local编辑模式

    下图表示是在Local模式下: 下图表示是在Global模式下: 不要搞反.

  3. Atitit.进程管理常用api

    Atitit.进程管理常用api 1 常用api 进程列表 getProcessList 是否存在某个进程判断 isExistProcess 启动进程run Sleep Exit Shutdown 作 ...

  4. C++语言基础(24)-四种类型转换运算符(static_cast、dynamic_cast、const_cast和reinterpret_cast)

    一.static_cast static_cast 只能用于良性转换,这样的转换风险较低,一般不会发生什么意外,如: #include <iostream> #include <cs ...

  5. 文件上传之 commons-fileupload(一)

    一 .简单介绍      使用最为广泛的Java文件上传组件,Struts本身采用这个包来处理文件上传.其基本原理:  FileUpload组件将页面提交的所有元素(普通form表单域,如text和文 ...

  6. poj2392 Space Elevator(多重背包问题)

    Space Elevator   Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8569   Accepted: 4052 ...

  7. KVC之-setValue:forKey:方法实现原理与验证

    KVC之-setValue:forKey:方法实现原理与验证 - (void)setValue:(id)value forKey:(NSString *)key方法,实现原理与验证 功能:使用一个字符 ...

  8. vue 单文件组件

    在很多vue项目中,我们使用vue.component来定义全局组件,紧接着用new Vue({el:'#container'})在每个页面内指定一个容器元素 这种方式在很多中小规模的项目中运作的很好 ...

  9. DIV的内容自动换行

    word-break:break-all和word-wrap:break-word都是能使其容器如DIV的内容自动换行. 它们的区别就在于: 1,word-break:break-all 例如div宽 ...

  10. ubuntu12.10更新源

    ubuntu12.10更新源 2013-03-10 20:48:17|  分类: Linux |字号 订阅   不同的网络状况连接以下源的速度不同, 建议在添加前手动验证以下源的连接速度(ping下就 ...