JAVA多线程与队列

原文地址为: JAVA多线程与队列

         JAVA 已经给我们提供了比较好的队列实现Queue,继承于Collection。 本次我使用的是BlockingQueue,继承于Queue。    

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

         首先利用BlockingQueue封装了一个队列类。队列里存放Map对象,这个依项目需求而定,供参考。

         

import java.util.AbstractMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
/**
* 单例的缓存map
*/

public class CachePool extends AbstractMap{

// 私有化缓存对象实例
private static CachePool cachePool = new CachePool();
private int maxCount = 1000;
private BlockingQueue queue = new LinkedBlockingQueue();
/**
* private Constructor.
* @return
*/
private CachePool() {
}
/**
* 开放一个公有方法,判断是否已经存在实例,有返回,没有新建一个在返回
* @return
*/
public static CachePool getInstance(){
return cachePool;
}

/**
* The Entry for this Map.
* @author AnCan
*
*/
private class Entry implements Map.Entry{
private Key key;
private Value value;

public Entry(Key key, Value value){
this.key = key;
this.value = value;
}

@Override
public String toString() {
return key + "=" + value;
}

public Key getKey() {
return key;
}

public Value getValue() {
return value;
}

public Value setValue(Value value) {
return this.value = value;
}
}



/**
* Constructor.
* @param size the size of the pooled map;
*/
public CachePool(int size) {
maxCount = size;
}

@Override
public Value put(Key key, Value value) {
while(queue.size() >= maxCount){
queue.remove();
}
queue.add(new Entry(key, value));
return value;
}

@Override
public Value get(Object key){
for(Iterator iter = queue.iterator();iter.hasNext();){
Entry type = iter.next();
if(type.key.equals(key)){
queue.remove(type);
queue.add(type);
return type.value;
}
}
return null;
}

@Override
public Set> entrySet() {
Set> set = new HashSet>();
set.addAll(queue);
return set;
}

@Override
public void clear() {
queue.clear();
}

@Override
public Set keySet() {
Set set = new HashSet();
for(Entry e : queue){
set.add(e.getKey());
}
return set;
}

@Override
public Value remove(Object obj) {
for(Entry e : queue){
if(e.getKey().equals(obj)){
queue.remove(e);
return e.getValue();
}
}
return null;
}

@Override
public int size() {
return queue.size();
}
}

            其中根据项目的需求重写了一些方法。

            先看下消费者类,使用多线程来处理队列中的内容:

      

import java.util.Date;
import java.util.Iterator;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;


/**
* 操作业务类,通过参数中的方法参数进行具体的操作
*/
public class TicketTradeOper extends HttpServlet
{
/**
* 缓存对象 map
*/
public static CachePool mapPool = CachePool.getInstance();

private static final int NTHREADS=5;
// 使用线程池来避免 为每个请求创建一个线程。
private static final Executor threadPool=Executors.newFixedThreadPool(NTHREADS);

//业务操作
IETicketTradeOper ticketTradeOper;

@Override
public void init() throws ServletException
{
Timer timer = new Timer();
timer.schedule(new TimerTask(){
@Override
public void run() {
startThread();
}
}, new Date(), 5000);//间隔5秒执行一次定时器任务
super.init();
}


public void startThread(){
threadPool.execute(new Runnable(){
public void run() {
executeCodeOper();
}
});
}

public void executeCodeOper()
{
String key = "";
Map param = null;
synchronized (mapPool)
{
System.out.println(Thread.currentThread().getName() + "进来了。。。。");
System.out.println("现在队列中共有----"+mapPool.size()+"---条数据");

Iterator it = mapPool.keySet().iterator();
//缓存不为空时,取出一个值
while (it.hasNext())
{
key = (String) it.next();
param = (Map) mapPool.get(key);
}
if (null != param)
{
//为防止重复,将其移除
mapPool.remove(key);
}
}

if (null != param)
{
boolean result =ticketTradeOperator(param);
System.out.println("此条数据处理========"+result);
if(!result){
//若处理失败,重新放回队列
mapPool.put(key, param);
};
}
}


public boolean ticketTradeOperator(Map params)
{
//具体的处理工作
return resultCode;
}

public IETicketTradeOper getTicketTradeOper()
{
return ticketTradeOper;
}
public void setTicketTradeOper(IETicketTradeOper ticketTradeOper)
{
this.ticketTradeOper = ticketTradeOper;
}

}
            生产者,根据业务需求将接收到的数据放到队列里:

     TicketTradeOper.mapPool.put(newParams.get("order_id"), newParams);


以上便是整个队列生产消费的过程,有问题的欢迎交流。

关于队列类Queue的介绍。下篇博客进行。。



         

  

转载请注明本文地址: JAVA多线程与队列

你可能感兴趣的:(JAVA多线程与队列)