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;
        }

    }

  • 相关阅读:
    springboot配置文件拆分
    SpringBoot中集成thymeleaf模板
    thymeleaf语法(二)
    thymeleaf的基本使用(一)
    js的for in循环和for of循环
    css动画箭头上线转动切换效果
    Gradle配置lintOptions
    使用IntelliJ IDEA创建Spring Boot项目
    SpringBoot的注解:
    Python的虚拟机安装已经如何配置Scrapy for Mac
  • 原文地址:https://www.cnblogs.com/komojoemary/p/thread.html
Copyright © 2011-2022 走看看