文档章节

线程池一:制作一个自定义线程池

小米墨客
 小米墨客
发布于 2016/02/02 20:05
字数 2198
阅读 147
收藏 4

[TOC]

####1.线程池概念

百度百科

线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务。线程池线程都是后台线程。每个线程都使用默认的堆栈大小,以默认的优先级运行,并处于多线程单元中。如果某个线程在托管代码中空闲(如正在等待某个事件),则线程池将插入另一个辅助线程来使所有处理器保持繁忙。如果所有线程池线程都始终保持繁忙,但队列中包含挂起的工作,则线程池将在一段时间后创建另一个辅助线程但线程的数目永远不会超过最大值。超过最大值的线程可以排队,但他们要等到其他线程完成后才启动。

####2.自定义线程池架构图

线程池流程图

  1. 用户新建任务#n,将任务#n加入到线程队列TaskList尾部位置,这里是任务#5后面
  2. 任务列表建立成功后,通过Dispath分配少于三个任务到线程池中(设定线程池最大支持3个任务)
  3. 线程池中任何一个任务执行完毕后,都会调用Dispath继续将任务加入到线程池中,直至线程队列TaskList中没有任何任务。

####3.代码实现线程池管理

1、初始化静态变量,单例实现。

public static synchronized TaskManager getInstance(Context context) {
    if (null == mInstance) {
        mInstance = new TaskManager();
    }
    return mInstance;
}

2、添加任务至线程队列

加入队列的流程,这里引出两个问题:(1)队列是怎么维护的?(2)调度是如何进行的? 问题(2)这里先不详述,说说问题(1)队列维护。

输入图片说明

private ArrayList<Task> mTaskList = new ArrayList<Task>();当前队列结构为ArrayList结构,添加和删除采用add和remove方法。 Task结构为:

/**
 * Task作为任务类,调用者可以对其进行重写
 *
 * Here is an example of subclassing:
 * 
 * <pre class="prettyprint">
 * 
 * class Mytask extends Task {
 *     private String mAction;
 * 
 *     public Mytask(String action, Object object) {
 *         super(action, object);
 *         mAction = action;
 *     }
 * 
 *     public void work() {
 *         // do your thread things
 *     }
 * }
 * </pre>
 */
public static class Task {
    /** 确保每个线程只执行一次 */
    private boolean mIsRunning;
    /** 当前线程键值 */
    protected String mAction;
    protected Object mObject;

    protected Task() {
    }

    protected Task(String action, Object object) {
        mAction = action;
        mObject = object;
    }

    protected void work() {
    }
}

设计该结构的缘由也是比较简单,设计一个运行标志位,当前行为和对应的值(Object类型),任务在protected void work() 中完成。

####4.任务调度Dispath (1)首先定义线程池的容量

ThreadPoolExecutor mThreadPool = (ThreadPoolExecutor) Executors.newFixedThreadPool(3);

/单线程队列池/ SINGLE_TASK_EXECUTOR = (ExecutorService) Executors.newSingleThreadExecutor(); /7个线程并行池/ LIMITED_TASK_EXECUTOR = (ExecutorService) Executors.newFixedThreadPool(7); /全部线程并行池/ FULL_TASK_EXECUTOR = (ExecutorService) Executors.newCachedThreadPool(); 这里用的是3个线程并行池。

(2)线程执行 参考下面流程图中的中间部分,线程中执行当前任务,调用Task#work()方法,其中用户实现放入work中,从队列中移除当前任务。

(3)hanlerEvent处理 收到线程中的handler请求,判断当前任务队列中是否依然存在任务,存在的话继续调用dispath处理任务。

输入图片说明

####5.执行效果

输入图片说明

(ThreadPoolExecutor) Executors.newFixedThreadPool(6);的时候参考效果为:

输入图片说明

####6.线程池完整代码粘贴 TaskManager.java

package com.example.zexception.thread;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;

import android.content.Context;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.os.Process;
import android.util.Log;

/**
 * TaskManager 处理http回调任务,使用线程池,任务队列 author: fxf createtime: 20160105
 */

public class TaskManager {

    private static final String TAG = TaskManager.class.getSimpleName();
    private static final int MAX_THREAD_SIZE = 6;
    private EventHandler mEventHandler;
    private HandlerThread mHandlerThread;
    private static TaskManager mInstance;
    private ArrayList<Task> mTaskList = new ArrayList<Task>();
    private ThreadPoolExecutor mThreadPool = (ThreadPoolExecutor) Executors.newFixedThreadPool(MAX_THREAD_SIZE);

    /**
     * Task作为任务类,调用者可以对其进行重写
     *
     * Here is an example of subclassing:
     * 
     * <pre class="prettyprint">
     * 
     * class Mytask extends Task {
     *     private String mAction;
     * 
     *     public Mytask(String action, Object object) {
     *         super(action, object);
     *         mAction = action;
     *     }
     * 
     *     public void work() {
     *         // do your thread things
     *     }
     * }
     * </pre>
     */
    public static class Task {
        /** 确保每个线程只执行一次 */
        private boolean mIsRunning;
        /** 当前线程键值 */
        protected String mAction;
        protected Object mObject;

        protected Task() {
        }

        protected Task(String action, Object object) {
            mAction = action;
            mObject = object;
        }

        protected void work() {
        }
    }

    public static synchronized TaskManager getInstance(Context context) {
        if (null == mInstance) {
            mInstance = new TaskManager();
        }
        return mInstance;
    }

    public TaskManager() {
        mHandlerThread = new HandlerThread("task listeners handler thread", Process.THREAD_PRIORITY_DEFAULT);
        mHandlerThread.start();
        mEventHandler = new EventHandler(this, mHandlerThread.getLooper());
    }

    /**
     * 添加线程任务,最小任务数目为0,最大{@link #MAX_THREAD_SIZE}
     * 
     * @author hanzhen01
     * @since 2016-02-02 17:17
     * 
     * @param item 需要插入的内容
     * 
     */
    public void addTaskRequest(Task item) {
        if (null == item) {
            return;
        }
        synchronized (mTaskList) {
            mTaskList.add(item);
        }
        dispatch();
    }

    /**
     * 任务调度,任务采用队列处理
     */
    private void dispatch() {
        /** 如果当前线程池已满 ,不再处理请求任务 */
        if (mThreadPool.getActiveCount() >= mThreadPool.getCorePoolSize()) {
            return;
        }
        /** 空闲线程的数量 */
        int spareThreads = mThreadPool.getCorePoolSize() - mThreadPool.getActiveCount();
        /** 如果请求列表中数量小于空闲的线程数,顺序处理请求 */
        synchronized (mTaskList) {
            for (int i = 0; i < mTaskList.size() && spareThreads > 0; i++) {
                if (!mTaskList.get(i).mIsRunning) {
                    execute(mTaskList.get(i));
                    mTaskList.get(i).mIsRunning = true;
                }
            }
        }
    }

    /**
     * 线程池执行操作,执行用户操作
     * 
     * @param request 任务请求
     */
    private void execute(final Task request) {

        mThreadPool.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    request.work();
                } catch (Exception e) {
                    Log.e(TAG, "request work excepation" + e.getMessage());
                }
                synchronized (mTaskList) {
                    mTaskList.remove(request);
                }
                Message msg = mEventHandler.obtainMessage();
                mEventHandler.sendMessage(msg);
            }
        });
    }

    /**
     * handler处理
     */
    class EventHandler extends Handler {
        private final WeakReference<TaskManager> mActivity;

        public EventHandler(TaskManager cb, Looper looper) {
            super(looper);
            mActivity = new WeakReference<TaskManager>(cb);
        }

        @Override
        public void handleMessage(Message msg) {
            TaskManager activity = mActivity.get();
            if (activity != null) {
                synchronized (mTaskList) {
                    if (mTaskList.size() > 0) {
                        activity.dispatch();
                    }
                }
            }
        }
    }

}


####7.demo代码粘贴

MainActivity.java

    /** thread ui */
    private SeekBar mBar1;
    private SeekBar mBar2;
    private SeekBar mBar3;
    private SeekBar mBar4;
    private SeekBar mBar5;
    private SeekBar mBar6;
    private int mTime = 100;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // setContentView(R.layout.activity_main);
        // initView();
        // function1();
        // initData();
        initViewThread();
    }

    /**
     * 线程池实现数据测试
     * 
     * 
     */
    private void initViewThread() {
        setContentView(R.layout.activity_thread_pool);
        mBar1 = (SeekBar) findViewById(R.id.seekBar1);
        mBar2 = (SeekBar) findViewById(R.id.seekBar2);
        mBar3 = (SeekBar) findViewById(R.id.seekBar3);
        mBar4 = (SeekBar) findViewById(R.id.seekBar4);
        mBar5 = (SeekBar) findViewById(R.id.seekBar5);
        mBar6 = (SeekBar) findViewById(R.id.seekBar6);
        TaskManager.getInstance(this).addTaskRequest(new Mytask("bar1", null));
        TaskManager.getInstance(this).addTaskRequest(new Mytask("bar2", null));
        TaskManager.getInstance(this).addTaskRequest(new Mytask("bar3", null));
        TaskManager.getInstance(this).addTaskRequest(new Mytask("bar4", null));
        TaskManager.getInstance(this).addTaskRequest(new Mytask("bar5", null));
        TaskManager.getInstance(this).addTaskRequest(new Mytask("bar6", null));
        mBar1.setMax(100);
        mBar2.setMax(100);
        mBar3.setMax(100);
        mBar4.setMax(100);
        mBar5.setMax(100);
        mBar6.setMax(100);
    }

    class Mytask extends Task {
        private String mKey;

        public Mytask(String key, String json) {
            super(key, json);
            mKey = key;
        }

        @Override
        public void work() {
            if ("bar1".equals(mKey)) {
                while (mBar1.getProgress() < 100) {
                    Message message = mMyHandler.obtainMessage();
                    message.what = 1;
                    message.arg1 = mBar1.getProgress() + 1;
                    if (0 == message.arg1 % 10) {
                        Log.i(TAG, "mBar1 number:" + message.arg1);
                    }
                    mMyHandler.sendMessage(message);
                    try {
                        Thread.sleep(mTime);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            } else if ("bar2".equals(mKey)) {
                while (mBar2.getProgress() < 100) {
                    Message message = mMyHandler.obtainMessage();
                    message.what = 2;
                    message.arg1 = mBar2.getProgress() + 1;
                    if (0 == message.arg1 % 10) {
                        Log.i(TAG, "mBar2 number:" + message.arg1);
                    }
                    mMyHandler.sendMessage(message);
                    try {
                        Thread.sleep(mTime);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            } else if ("bar3".equals(mKey)) {
                while (mBar3.getProgress() < 100) {
                    Message message = mMyHandler.obtainMessage();
                    message.what = 3;
                    message.arg1 = mBar3.getProgress() + 1;
                    if (0 == message.arg1 % 10) {
                        Log.i(TAG, "mBar3 number:" + message.arg1);
                    }
                    mMyHandler.sendMessage(message);
                    try {
                        Thread.sleep(mTime);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            } else if ("bar4".equals(mKey)) {
                while (mBar4.getProgress() < 100) {
                    Message message = mMyHandler.obtainMessage();
                    message.what = 4;
                    message.arg1 = mBar4.getProgress() + 1;
                    if (0 == message.arg1 % 10) {
                        Log.i(TAG, "mBar4 number:" + message.arg1);
                    }
                    mMyHandler.sendMessage(message);
                    try {
                        Thread.sleep(mTime);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            } else if ("bar5".equals(mKey)) {
                while (mBar5.getProgress() < 100) {
                    Message message = mMyHandler.obtainMessage();
                    message.what = 5;
                    message.arg1 = mBar5.getProgress() + 1;
                    if (0 == message.arg1 % 10) {
                        Log.i(TAG, "mBar5 number:" + message.arg1);
                    }
                    mMyHandler.sendMessage(message);
                    try {
                        Thread.sleep(mTime);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            } else if ("bar6".equals(mKey)) {
                while (mBar6.getProgress() < 100) {
                    Message message = mMyHandler.obtainMessage();
                    message.what = 6;
                    message.arg1 = mBar6.getProgress() + 1;
                    if (0 == message.arg1 % 10) {
                        Log.i(TAG, "mBar6 number:" + message.arg1);
                    }
                    mMyHandler.sendMessage(message);
                    try {
                        Thread.sleep(mTime);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    @SuppressLint("HandlerLeak")
    private Handler mMyHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case 1:
                    mBar1.setProgress(msg.arg1);
                    break;
                case 2:
                    mBar2.setProgress(msg.arg1);
                    break;
                case 3:
                    mBar3.setProgress(msg.arg1);
                    break;
                case 4:
                    mBar4.setProgress(msg.arg1);
                    break;
                case 5:
                    mBar5.setProgress(msg.arg1);
                    break;
                case 6:
                    mBar6.setProgress(msg.arg1);
                    break;

                default:
                    break;
            }
        }
    };

R.layout.activity_thread_pool.xml文件

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:padding="10dp" >

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Task#1"
            android:textAppearance="?android:attr/textAppearanceLarge" />

        <SeekBar
            android:id="@+id/seekBar1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1" />

    </LinearLayout>

    <View
        android:layout_width="match_parent"
        android:layout_height="1px"
        android:background="#dddddd"/>
        <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:padding="10dp" >

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Task#2"
            android:textAppearance="?android:attr/textAppearanceLarge" />

        <SeekBar
            android:id="@+id/seekBar2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1" />

    </LinearLayout>

    <View
        android:layout_width="match_parent"
        android:layout_height="1px"
        android:background="#dddddd"/>
        <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:padding="10dp" >

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Task#3"
            android:textAppearance="?android:attr/textAppearanceLarge" />

        <SeekBar
            android:id="@+id/seekBar3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1" />

    </LinearLayout>

    <View
        android:layout_width="match_parent"
        android:layout_height="1px"
        android:background="#dddddd"/>
        <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:padding="10dp" >

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Task#4"
            android:textAppearance="?android:attr/textAppearanceLarge" />

        <SeekBar
            android:id="@+id/seekBar4"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1" />

    </LinearLayout>

    <View
        android:layout_width="match_parent"
        android:layout_height="1px"
        android:background="#dddddd"/>
        <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:padding="10dp" >

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Task#5"
            android:textAppearance="?android:attr/textAppearanceLarge" />

        <SeekBar
            android:id="@+id/seekBar5"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1" />

    </LinearLayout>

    <View
        android:layout_width="match_parent"
        android:layout_height="1px"
        android:background="#dddddd"/>
        <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:padding="10dp" >

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Task#6"
            android:textAppearance="?android:attr/textAppearanceLarge" />

        <SeekBar
            android:id="@+id/seekBar6"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1" />

    </LinearLayout>

    <View
        android:layout_width="match_parent"
        android:layout_height="1px"
        android:background="#dddddd"/>

</LinearLayout>

© 著作权归作者所有

小米墨客
粉丝 67
博文 16
码字总数 65581
作品 0
海淀
程序员
私信 提问
java 线程之executors线程池

一、线程池的作用   平时的业务中,如果要使用多线程,那么我们会在业务开始前创建线程,业务结束后,销毁线程。但是对于业务来说,线程的创建和销毁是与业务本身无关的,只关心线程所执行...

xsster
2017/07/28
0
0
线程池之ThreadPoolExecutor使用

ThreadPoolExecutor提供了四个构造方法: 我们以最后一个构造方法(参数最多的那个),对其参数进行解释: 如果对这些参数作用有疑惑的请看 ThreadPoolExecutor概述。 知道了各个参数的作用后...

天王盖地虎626
06/24
49
0
Android多线程操作——线程池管理综述

题记—— 难过了,悄悄走一走; 伤心了,默默睡一觉; 优雅不是训练出来的,而是一种阅历; 淡然不是伪装出来的,而是一种沉淀; 时间飞逝,老去的只是我们的容颜; 时间仿佛一颗灵魂,越来越...

赵子龙
2016/07/24
551
1
(深度)Java 多线程系列(2):使用线程池 ThreadPoolExecutor

原文地址:https://segmentfault.com/a/1190000007925310 首先,我们为什么需要线程池? 让我们先来了解下什么是 对象池 技术。某些对象(比如线程,数据库连接等),它们创建的代价是非常大...

芝麻粒儿
03/23
0
0
J.U.C并发包之Executor与线程池

在创建对象的过程中,创建对象,是在 JVM 的堆里分配一块内存;而创建一个线程,需要调用操作系统内核的 API,然后操作系统要为线程分配一系资源 池化资源与线程池的区别 池化资源是指把资源...

语落心生
07/08
0
0

没有更多内容

加载失败,请刷新页面

加载更多

CSS--属性

一、溢出 当内容多,元素区域小的时候,就会产生溢出效果,默认是纵向溢出 横向溢出:在内容和容器之间再套一层容器,并且内部容器要比外部容器宽 属性:overflow/overflow-x/overflow-y 取值...

wytao1995
36分钟前
4
0
Confluence 6.15 使用附件宏

希望添加附件宏到一个页面中: 从编辑工具栏中,选择 插入(Insert) > 其他宏(Other Macros) 找到并且选择需要的宏。 可用使用自动完成加快这个过程:输入 { 然后开始输入你希望插入的宏的...

honeymoose
56分钟前
4
0
精华帖

第一章 jQuery简介 jQuery是一个JavaScript库 jQuery具备简洁的语法和跨平台的兼容性 简化了JavaScript的操作。 在页面中引入jQuery jQuery是一个JavaScript脚本库,不需要特别的安装,只需要...

流川偑
今天
6
0
语音对话英语翻译在线翻译成中文哪个方法好用

想要进行将中文翻译成英文,或者将英文翻译成中文的操作,其实有一个非常简单的工具就能够帮助完成将语音进行翻译转换的软件。 在应用市场或者百度手机助手等各大应用渠道里面就能够找到一款...

401恶户
今天
3
0
jenkins 插件下载加速最终方案

推荐做法 1、告诉jenkins 我哪些插件需要更新 jenkins插件清华大学镜像地址 https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json 1.进入jenkins系统管理 2.进入插件管...

vasks
今天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部