继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

迫于无奈我使用了多线程

Caeser110
关注TA
已关注
手记 139
粉丝 29
获赞 154

迫于无奈我使用了多线程

前言

项目上很多代码都是在原有代码的基础上做修改,以尽快满足需求,最近在修改公司代码的时候,我在调试一个JSP页面,给页面加了一个日期,然后这个日期会赋值给另一个表的字段,是一个很简单的需求,但是另一个表的那条数据是延迟产生的,至于是怎么延迟的,我还没能一步步调试出来,只知道确实是延迟,但是是在哪一段代码延迟的,我是真的找不到了,因为单步调试JS然后跟踪断点,肯定是没错的,但就是这样一步步调试,我还是没能找到哪一步进行了延迟操作,我只是觉得应该是ajax异步导致的,我对这个问题研究了很久,还是没能研究好公司的源代码,于是我打算铤而走险,创建线程来判断什么时候产生了那条数据,然后进行赋值,算是“曲线救国”吧!

关于多线程的理解

图片描述
我在练习多线程开发的时候,并没有应用到实际的业务需求上,所以理解不深刻。但是经常可以遇到的时候,很多时候不清楚某一条数据或者是某段代码何时执行出现,但是整个主程序又不能在这里Sleep等待,于是就需要一个可以返回的,异步的代码段,也就是多线程,主程序可以正常结束,新建的线程继续等待,直到这条数据可以返回为止。
这里有个隐藏的异常,就是如果新建的线程一直等待不到数据,那么很可能会卡死在判断那里,造成大量线程产生而无法结束。

示意图

如果是延迟产生数据 ,此时要么等待,要么赋空值。如果是等待,则整个程序都在等这段代码,于是延迟产生的数据还是不能产生,而赋空值就会不满足需求。
图片描述

代码

package cn.caeser.Ajax;


import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.text.DateFormat;

public class CaeThreadCharge extends BaseRequest {
    private TargetFromWeb ajaxResponse;

    @Override
    public void myRequest(HttpServletRequest arg0, HttpServletResponse arg1, ServletContext servletContext) throws ServletException {
        ajaxResponse=new TargetFromWeb(arg0, arg1);

        String whichMethod=ajaxResponse.getRequestParameter("whichMethod","");

        switch (whichMethod) {
            case "changeDate":
                changeDate();
                break;
            default:
                break;
        }
    }
    private void changeDate(){
        // 获取消费编号
        String customIdStr = ajaxResponse.getRequestParameter("customId","");
        // 工人编号
        String workerNumber = ajaxResponse.getRequestParameter("workernumber","");
        // 前端选择的日期
        String choosenDate = ajaxResponse.getRequestParameter("choosendate","");
        if ("".equals(customIdStr)||"".equals(workerNumber)||"".equals(choosenDate)){
            // 提前判空,增加返回出口,减少大段的括号
            return;
        }
        // 创建线程循环查找是指定数据
        Thread getSampleIdThread=new Thread(new GetTargetItemThread(this,customIdStr,choosenDate,workerNumber));
        // 启动线程
        getSampleIdThread.start();

    }
    class GetTargetItemThread implements Runnable{
        // 传值类
        private Integer fwt;
        private String customIdStr;
        private String choosenDate;
        private String workerNumber;
        GetTargetItemThread(Integer  ofwt,String sa,String sb,String sc){
            this.fwt=ofwt;
            this.customIdStr=sa;
            this.choosenDate=sb;
            this.workerNumber=sc;
        }
        public void run() {
            StringBuilder sbGetCustomId = new StringBuilder();
            DataMap dmGetMapById=null;
            sbGetCustomId.append("select customId from custom where customId='"+customIdStr+"' and workerNumber='"+workerNumber+"'");
            do{
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                dmGetMapById = fwt.mMap;
                // 判断是否查找到指定数据
            }while(!(dmGetMapById!=null&&dmGetMapById.size()>0));
            // 如果查找到
            System.out.println("赋值");
        }
    }
}

代码解释

我是通过实现Runnale接口来创建线程的,当do while循环结束之后,整个run方法里的代码执行结束,线程的代码就执行到结尾了。
这里的变量和参数都是我自己修改后再展示的,不然我也不可能把公司里的代码拿出来展示。
为了减少大段的括号包裹代码段,我增加了代码返回的出口,以增加代码的可阅读性。

总结

图片描述
其实我也只是记录一下,一个非常常见的业务需求是如何为了加快项目进度快速实现的方式,大部分赶进度其实都是这样的,可能我这份代码确实不够优雅,因为主要原因还是我没能读懂所有公司的源码,不能在延迟产生数据的下面加上赋值代码,我们在实现业务的时候,大部分情况都是尽量避免修改源码,尽量只增加不减少,尽量只往整体架构上“插入”代码。

打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP