zoukankan      html  css  js  c++  java
  • 线程管理工具类(支持单线程队列以及多线程并发)

           我们开发的过程中,如果某个动作耗时过长,我们又不想等待;如果某个动作需要定时不断执行;如果我们想同时做几件事情;我们就需要使用到线程了。线程里面运用最多的,无疑就是单线程的队列管理,或者多线程并发执行了。这种情况有1个经典的应用场景,也是个人至今做的唯一的一个J2ME项目中的运用:处理http请求。

           那个是我工作第一年做的唯一的一个项目,对手机客户端开发感兴趣的应该有所了解,是移动的一个定制项目:手机阅读。现在已经全国推广使用了,各种机型应该都可以下载到适用的客户端。那个时候真的是个菜鸟,刚刚毕业,写起代码来就像摸着石头过河,一步一徘徊。团队里面有个工作第2年的算是老鸟的一个写手,处理http请求这块的内容,因为客户端与服务器之间是用http通讯的,所有数据都需要从服务端获取,在手机上展示,所以http工具类的重要性不言而喻,经过1个多月的反复推倒重来,测试修改,终于完工。其实代码并不多,核心的也就1个类,几百行而已。算下来,一个月平均每天也就码了40多行。至此,我对华为的那个团队负责人是深感佩服:他在编码开工会上说:“一个好的程序员,1天能写出的优秀代码也不过是百行不到,所以你们不要追求速度,慢慢来,质量最重要。”那个时候我们还在嗤之以鼻,1天少说也写个几百上千行啊,百行不到不是笑死人。之后大半年的时间,果然证明姜还是老的辣。我们花了2个月完成整个客户端代码的编写,却花了6个月在代码的review和重构上,也就是在那个时候,编码的一些好的习惯,以及对于代码质量的重视深深扎根在我心间。一直延续到如今的工作中。

          当然很多做web项目的人不会有机会对代码做如此扣的动作,因为review和重构意味着工作量的增加,劳动成本的提升,开销的加大,这些都是你的上司所不希望见到的。他们常常希望你做出来的东西只要能用,满足条件即可,不会去关注代码的质量问题,时间是第一位的,因为要上线,要验收,要赚钱。当然,一些强大的web服务器足以弥补很多代码上的不足,所以一份好的代码越来越难出现在这样的队伍中。我目前处于的环境就是这样,万幸的是:我处于公司java组的框架开发团队,这使得我有机会延续之前好的习惯,感谢老天 ,没有让我去做枯燥无味的重复体力劳动(具体项目的开发)。

         闲话不多说,回归主题。因为近期用到了线程,所以回想了之前项目中的使用场景:多线程并发(同时进行多本书的下载);单线程队列(一个页面上面普通的http请求,进行了队列的管理)。下面贴出核心代码。

    包含2个文件:ThreadManageUtil ,ThreadObject 大家可以直接拷贝使用

    import java.util.ArrayList;
    import java.util.List;

    /**
     * 线程管理工具类
     *
     * @作者 komojoemary
     * @version [版本号, 2011-2-24]
     * @see [相关类/方法]
     * @since [产品/模块版本]
     */
    public class ThreadManageUtil implements Runnable
    {
        /**
         * 请求队列(用于单线程)
         */
        private static List<ThreadObject> requestList = null;

        /**
         * 同步对象(用于单线程)
         */
        private static Object object = new Object();

        /**
         * ThreadManageUtil对象的实例(用于单线程)
         */
        private static ThreadManageUtil instance = null;

        /**
         * 当前的请求对象
         */
        private ThreadObject currentRequest = null;

        /**
         * 是否为多线程运行
         */
        private boolean isMultiThread = false;

        /**
         * 运行线程
         *
         * @param 无
         * @return 无
         * @exception/throws 无
         * @see 无
         */
        public void run() {
            // 如果为多线程
            if (isMultiThread) {
                runHandle();
            }
            // 非多线程
            else {
                while (true) {
                    // 如果不为空则为超时需要重连的请求,不从队列里重新获取
                    if (currentRequest == null) {
                        synchronized (object) {
                            // 队列不为空
                            if (requestList.size() > 0) {
                                // 从队列中获取请求
                                currentRequest = (ThreadObject) requestList.get(0);
                                // 从请求队列中将当前请求删除
                                requestList.remove(0);
                            }
                            else {
                                try {
                                    // 队列为空则交出对象锁,等待唤醒
                                    object.wait();
                                    continue;
                                }
                                catch (InterruptedException e) {
                                    e.printStackTrace();
                                }
                            }
                        }
                    }
                    runHandle();
                    currentRequest = null;
                }
            }
        }

        /**
         *
         * 请求过程处理 过程
         *
         * @param 无
         * @return 无
         * @exception/throws 无 无
         * @see 无
         */
        private void runHandle() {
            try {
                currentRequest.handleOperation();
                Thread.yield();
            }
            catch (Exception ce) {
                ce.printStackTrace();
            }
        }

        /**
         *
         * 启动线程 当用单线程多任务排队请求时,将请求添加至请求队列中。当请求的是多线程时,开辟一个新的线程
         *
         * @param request
         *            请求对象
         * @return 无
         * @exception/throws 无
         */
        public static void sendRequest(ThreadObject request) {
            // 多线程
            if (request.isMultiThread()) {
                ThreadManageUtil downloadHttp = new ThreadManageUtil();
                downloadHttp.isMultiThread = true;
                downloadHttp.currentRequest = request;
                new Thread(downloadHttp).start();
            }
            else {
                // 单线程请求排队
                if (instance == null) {
                    // 在当前线程对象为空时才进行线程初始化操作,同时初始化队列
                    instance = new ThreadManageUtil();
                    requestList = new ArrayList<ThreadObject>();
                    new Thread(instance).start();
                }
                insertReqList(request);
            }
        }

        /**
         *
         * 请求添加方法
         *
         * @param request
         *            需要添加的请求
         * @return 无
         * @exception/throws 无
         * @see 无
         */
        private static void insertReqList(ThreadObject request) {
            synchronized (object) {
                requestList.add(request);
                object.notify();
            }
        }

    }


    /**
     * 线程执行对象
     *
     * @作者 komojoemary
     * @version [版本号, 2011-2-24]
     * @see [相关类/方法]
     * @since [产品/模块版本]
     */
    public abstract class ThreadObject
    {
        /**
         * 是否多线程
         */
        private boolean multiThread = false;

        /**
         * 是否处理完成
         */
        private boolean isOk = false;

        /**
         * 线程处理操作
         *
         * @exception/throws [违例类型] [违例说明]
         * @see [类、类#方法、类#成员]
         */
        public abstract Object handleOperation();

        public boolean isMultiThread() {
            return multiThread;
        }

        public void setMultiThread(boolean multiThread) {
            this.multiThread = multiThread;
        }

        public boolean isOk() {
            return isOk;
        }

        public void setOk(boolean isOk) {
            this.isOk = isOk;
        }

    }

  • 相关阅读:
    ICONS-图标库
    图形资源
    vue项目中,如果修改了组件名称,vscode编辑器会在引入修改组件的名字处提示红色波浪线 The file is in the program because:Imported via xxx Root file specified for compilation .
    接口在dev环境报跨域问题(has been blocked by CORS policy:Response to preflight request doesn't pass access control check:No 'Access-Control-Allow-Origin' header ispresent on the requested resource.),qa环境正常
    阿里云occ的图片文件URL用浏览器直接打开无法访问,提示This XML file does noe appear to have any style information associated with it. The document tree is shown below.
    vue 项目使用element ui 中tree组件 check-strictly 用法(父子不互相关联的反显情况)
    高德地图进行线路规划绘制标记点操作(vue)
    vue中实现拖拽调整顺序功能
    2021-01-22 浏览器相关知识
    2021-01-22 js 相关知识点
  • 原文地址:https://www.cnblogs.com/komojoemary/p/thread.html
Copyright © 2011-2022 走看看