实现队列处理数据
需求描述:已有的数据接收接口为单线程,由于数据量激增压力过大,改进成项目启动时创建两个新线程,一个接收数据直接存入队列,另一个处理队列中的数据,没有时等待。
实现过程中遇到的问题写在前面。
- Java静态方法中依赖注入调用Service层问题。
@Autowired
private GatedateManager GatedateService;
@Autowired
private YjzjbkManager YjzjbkService ;
public static QueueTest QueueTest;
@PostConstruct
public void init(){
QueueTest=this;
QueueTest.GatedateService=this.GatedateService;
QueueTest.YjzjbkService=this.YjzjbkService;
}
PageData station = QueueTest.GatedateService.findByStation(pd);// 调用时
问题处理思路:
1. 我们创建一个监听的类,继承ServletContextListener,用于项目启动时执行。
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import com.ycgis.controller.alertinfo.alertinfo.QueueTest.Input;
import com.ycgis.controller.alertinfo.alertinfo.QueueTest.Test14;
public class MyListener implements ServletContextListener {
private Input myThread;
private Test14 myThread1;
@Override
public void contextDestroyed(ServletContextEvent arg0) {
if(myThread != null && myThread.isInterrupted()) {
myThread.interrupt();
}
}
@Override
public void contextInitialized(ServletContextEvent arg0) {
String str = null;
if (str == null && myThread == null) {
// myThread = new Input();
myThread1 = new Test14();
// myThread.start(); // servlet 上下文初始化时启动 socket
myThread1.start();
}
}
}
2.自定义一个 Class 线程类,并初始化队列。
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Queue;
import java.util.Scanner;
import java.util.Set;
import java.util.concurrent.LinkedBlockingQueue;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringEscapeUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class QueueTest{
//@Resource(name="GatedateService")
@Autowired
private GatedateManager GatedateService;
@Autowired
private YjzjbkManager YjzjbkService ;
public static QueueTest QueueTest;
@PostConstruct
public void init(){
QueueTest=this;
QueueTest.GatedateService=this.GatedateService;
QueueTest.YjzjbkService=this.YjzjbkService;
}
public static final Queue<String> queue = new LinkedBlockingQueue();
public static String qtype = "1";
static class Input extends Thread{// 接收控制台输入
public void run(){
// String name = null;
// Scanner sc = new Scanner(System.in);
// System.out.println("请输入字符串:");
while(true){
// name=sc.nextLine();
//// // 如果立即可行且不违反容量限制,
//// // 则将指定的元素插入此双端队列表示的队列中(即此双端队列的尾部),
//// // 并在成功时返回 true;如果当前没有空间可用,则返回 false
// queue.offer(name);
// if ("exit".equals(name))
// break;
if(queue.size()>0){
synchronized (queue){//notify()是Object()中定义的方法所以只能用在synchronized()方法中。
queue.notify();//唤醒在负责输出线程中的等待的告诉队列中有元素了它可以输出了
System.err.println("我是唤醒:当前队列中有新增内容!");
}
}
}
}
}
static class Test14 extends Thread{
public void run(){
while(true){
if(queue.size()>0){
String name = queue.poll();
JSONArray arr = JSONArray.fromObject(name);
try{
for(int i=0;i<arr.size();i++){
PageData pd = new PageData();
PageData pdts = new PageData();
PageData pdqc = new PageData();//去重
JSONObject job = arr.getJSONObject(i);
if(job!=null){
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
pd.put("ID",UuidUtil.get32UUID());
pd.put("TYPE","");
}
}
}catch (Exception e){
e.printStackTrace();
}
}else{
synchronized (queue){
try {
queue.wait();//相当于queue.wait(0),队列中没有东西则默认无限等待直到队列中有东西并且通知他
}catch (InterruptedException e) {
e.printStackTrace();
}//如果队列中没有东西则等待
}
}
}
}
}
}
3. 配置web监听
<listener>
<listener-class>com.aaaa.controller.alertinfo.alertinfo.MyListener</listener-class>
</listener>
4. 正式接口来数据时的调用。
import java.util.HashMap;
import java.util.Map;
import javax.annotation.Resource;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
@RequestMapping(value="/appgate")
public class IntGateinfoController extends BaseController {
@RequestMapping(value="/getgate")
@ResponseBody
public Object getAlert(@RequestBody String format,String token,String uname) throws Exception{
logBefore(logger, "获取到json数据");
Map<String,Object> map = new HashMap<String,Object>();
String ret = "";
PageData kp = new PageData();
kp.put("TO_KEN", token);
kp.put("KEYNAME", uname);
kp.put("FORMAT", format);
PageData ibs = new PageData();
ibs.put("KEYNAME", "yjryxx");
try{
if(ibs!=null && MD5.md5(ibs.getString("KEYNAME")).equals(uname)){
if(AppUtil.checkParam("getCheckPerson", kp)){
String str = QueueTest.qtype;
if(str.equals("1")){
ret = "01";
QueueTest.queue.offer(format);
synchronized (QueueTest.queue){
QueueTest.queue.notify();
}
}else{
ret="00";
}
}else {
ret = "03";
}
}else{
ret = "05";
}
}catch (Exception e){
logger.error(e.toString(), e);
ret="00";
}finally{
map.put("result", ret);
logAfter(logger);
}
return AppUtil.returnObject(new PageData(), map);
}
}