160801、BlockingQueue处理多线程

前面介绍过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文档


  

时间: 2024-10-13 14:02:43

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

Chapter 3-01

Please indicate the source: http://blog.csdn.net/gaoxiangnumber1 Welcome to my github: https://github.com/gaoxiangnumber1 第3章多线程服务器的适用场合与常用编程模型 ?"两个进程不在同一台机器上"指的是逻辑上不在同一个操作系统里运行,虽然物理上可能位于同一机器虚拟出来的两台"虚拟机"上. 3.1 进程与线程 ?一个进程是"内存中正在运行

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

在JAVA的Concurrent包中,BlockingQueue很好的解决了多线程中,如何高效安全“传输”数据的问题.通过这些高效并且线程安全的队列类,为我们快速搭建高质量的多线程程序带来极大的便利.本文详细介绍了BlockingQueue家庭中的所有成员,包括他们各自的功能以及常见使用场景. 一.认识BlockingQueue 阻塞队列,顾名思义,首先它是一个队列,而一个队列在数据结构中所起的作用大致如下图所示:  从上图我们可以很清楚看到,通过一个共享的队列,可以使得数据由队列的一端输入,从

Java多线程-工具篇-BlockingQueue

前言: 在新增的Concurrent包中,BlockingQueue很好的解决了多线程中,如何高效安全"传输"数据的问题.通过这些高效并且线程安全的队列类,为我们快速搭建高质量的多线程程序带来极大的便利.本文详细介绍了BlockingQueue家庭中的所有成员,包括他们各自的功能以及常见使用场景. 认识BlockingQueue阻塞队列,顾名思义,首先它是一个队列,而一个队列在数据结构中所起的作用大致如下图所示:从上图我们可以很清楚看到,通过一个共享的队列,可以使得数据由队列的一端输入

[转载] java多线程学习-java.util.concurrent详解(四) BlockingQueue

转载自http://janeky.iteye.com/blog/770671 --------------------------------------------------------------------------------- 7.BlockingQueue     “支持两个附加操作的 Queue,这两个操作是:获取元素时等待队列变为非空,以及存储元素时等待空间变得可用.“ 这里我们主要讨论BlockingQueue的最典型实现:LinkedBlockingQueue 和Arra

Java多线程系列十——BlockingQueue类

参考资料:http://ifeve.com/java-synchronousqueue/http://www.cnblogs.com/jackyuj/archive/2010/11/24/1886553.htmlhttp://ifeve.com/java-blocking-queue/ BlockingQueue的几个API认识 方法 说明 add(E e) 添加元素,超出队列size上限后抛异常 offer(E e) 添加元素,超出队列size上限后抛异常,相比add官方更建议使用offer方

[Java基础] Java多线程-工具篇-BlockingQueue

转载自: http://www.cnblogs.com/jackyuj/archive/2010/11/24/1886553.html 前言: 在新增的Concurrent包中,BlockingQueue很好的解决了多线程中,如何高效安全“传输”数据的问题.通过这些高效并且线程安全的队列类,为我们快速搭建高质量的多线程程序带来极大的便利.本文详细介绍了BlockingQueue家庭中的所有成员,包括他们各自的功能以及常见使用场景. 认识BlockingQueue 阻塞队列,顾名思义,首先它是一个

Java多线程与并发库高级应用之阻塞队列BlockingQueue

JDK1.5提供了阻塞队列接口BlockingQueue,它是一个有界阻塞队列.BlockingQueue实现是线程安全的,可以安全地与多个生产者和多个使用者一起使用. 使用时用其实现类 ArrayBlockingQueue,它一个由数组支持的有界阻塞队列.此队列按 FIFO(先进先出)原则对元素进行排序.队列的头部 是在队列中存在时间最长的元素.队列的尾部是在队列中存在时间最短的元素.新元素插入到队列的尾部,队列获取操作则是从队列头部开始获得元素. 这是一个典型的"有界缓存区",固定

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

Queue是什么 队列,是一种数据结构.除了优先级队列和LIFO队列外,队列都是以FIFO(先进先出)的方式对各个元素进行排序的.无论使用哪种排序方式,队列的头都是调用remove()或poll()移除元素的.在FIFO队列中,所有新元素都插入队列的末尾. Queue中的方法 Queue中的方法不难理解,6个,每2对是一个也就是总共3对.看一下JDK API就知道了: 注意一点就好,Queue通常不允许插入Null,尽管某些实现(比如LinkedList)是允许的,但是也不建议. Blockin

多线程学习之BlockingQueue

前言: 在新增的Concurrent包中,BlockingQueue很好的解决了多线程中,如何高效安全“传输”数据的问题.通过这些高效并且线程安全的队列 类,为我们快速搭建高质量的多线程程序带来极大的便利.本文详细介绍了BlockingQueue家庭中的所有成员,包括他们各自的功能以及常见使用场 景. 认识BlockingQueue阻塞队列,顾名思义,首先它是一个队列,而一个队列在数据结构中所起的作用大致如下图所示:从上图我们可以很清楚看到,通过一个共享的队列,可以使得数据由队列的一端输入,从另