线程池的使用(三)

来源:互联网 发布:办公室饿 知乎 编辑:程序博客网 时间:2024/06/03 21:37

一.概述

今天我们继续研究线程池的使用,因为这块确实可能比较麻烦,不多研究几次是根本不能搞懂的,先看效果图

效果一

这里写图片描述

效果二

这里写图片描述

二.代码

效果一(纯ExecutorService、AsyncTask、Runnable关联实现相关文件如下)

public class MainActivity extends AppCompatActivity {    private static final String TAG = "MainActivity";    //任务编号    private static int order = 0;    /**     * 总共多少任务(根据CPU个数决定创建活动线程的个数,这样取的好处就是可以让手机承受得住)     *///    private static final int count = Runtime.getRuntime().availableProcessors()*2;    private static final int count = 6;//任务总数    /**     * 每次只执行一个任务的线程池     */    private static ExecutorService sSingleThreadExecutor;    /**     * 没有任务个数限制的线程池     */    private static ExecutorService sCachedThreadPool;    /**     * 限制任务个数的线程池     */    private static ExecutorService sFixedThreadPool;    /**     * 按指定时间可周期性执行任务的线程池     */    private static ExecutorService sScheduledThreadPool;    /**     * 按指定时间可周期性执行任务的线程池,按照指定的工厂模式     */    private static ExecutorService sScheduledThreadPool1;    private List<PoolTask> mPoolTasks;    private ListView mListView;    private boolean isCancel = false;    private boolean isClick = false;    /**     * 当前线程执行器类型     */    private static ExecutorService currentExecutor ;    /**     * 方式一,使用默认线程工厂     */    ThreadFactory ft = Executors.defaultThreadFactory();    /**     * 方式二,创建新线程需要的线程工厂     */    private static ThreadFactory mThreadFactory = new ThreadFactory() {        private final AtomicInteger count = new AtomicInteger();        @Override        public Thread newThread(Runnable r) {            Thread thread = new Thread(r, "threadPool" + count.getAndIncrement());            thread.setDaemon(true);            return thread;        }    };    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        mListView = (ListView) findViewById(R.id.listview);        mListView.setOnItemClickListener(mOnItemClickListener);        initData();    }    public void initData(){        sSingleThreadExecutor = Executors.newSingleThreadExecutor();        sCachedThreadPool = Executors.newCachedThreadPool();        sFixedThreadPool = Executors.newFixedThreadPool(3);        sScheduledThreadPool = Executors.newScheduledThreadPool(3);        sScheduledThreadPool1 = Executors.newScheduledThreadPool(4, mThreadFactory);        sSingleThreadExecutor.submit(new Runnable() {            @Override            public void run() {                Log.i(TAG, "run: task is sumbit");            }        });        currentExecutor = sSingleThreadExecutor;        mListView.setAdapter(new ThreadPoolAdapter(this, count));    }    AdapterView.OnItemClickListener mOnItemClickListener = new AdapterView.OnItemClickListener() {        @Override        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {            if (position == 0) {                //第一种关闭方式,等待正在执行的任务执行完成//                    sCachedThreadPool.shutdown();                    /*                    shutdownNow:停止正在执行的任务,返回未执行的任务列表,第二次再调用shutDown                    不会返回未执行的任务列表,当前执行器会变为空,因为线程池已经关闭了                     */                System.out.println("=========currentExecutor"+currentExecutor);                List<Runnable> runnables = currentExecutor.shutdownNow();                System.out.println("==========="+runnables);                for (Runnable r : runnables) {                    System.out.println("=========未执行的任务信息"+r.toString());                }                System.out.println("=========isShoutDown"+currentExecutor.isShutdown());                currentExecutor = null;            }            //以第二项为例进行测试            PoolTask poolTask = mPoolTasks.get(1);            if (position == 1) {                if (!isClick) {                    poolTask.cancel(true);                    isCancel = true;                    isClick = !isClick;                } else {                    poolTask.cancel(false);                    isCancel = false;                    isClick = !isClick;                    if (poolTask != null && poolTask.getStatus() == AsyncTask.Status.RUNNING) {                        if (poolTask.isCancelled()) {                            poolTask = new PoolTask(poolTask.itemview);                        } else {                            Toast.makeText(MainActivity.this, "任务已经在执行", Toast.LENGTH_SHORT).show();                        }                    }                    if (currentExecutor == null) {                        currentExecutor = Executors.newCachedThreadPool();                    }                    poolTask.executeOnExecutor(currentExecutor);//只能执行一次,也就是说第二个只能点击两次                }            } else {                Toast.makeText(MainActivity.this, "其他的", Toast.LENGTH_SHORT).show();                poolTask.cancel(false);                isCancel =false;            }        }    };    class PoolTask extends AsyncTask<Void, Integer, Void> {        private View itemview;        private final TextView mTextView;        private final ProgressBar mPb;        private String id;        public PoolTask(View itemview){            this.itemview = itemview;            mTextView = (TextView) itemview.findViewById(R.id.textview);            mPb = (ProgressBar) itemview.findViewById(R.id.pb);            if(order<count ||order == count){                id = "执行:" + String.valueOf(++order);            }else{                order = 0;                id = "执行:" + String.valueOf(++order);            }        }        @Override        protected void onPreExecute() {            super.onPreExecute();            mTextView.setText(id);        }        @Override        protected Void doInBackground(Void... params) {            if(!isCancelled()&&isCancel == false){ //这个地方很关键,如果不设置标志位的话,直接setCancel(true)是无效的                int prog = 0;                while (prog<101){                    if ((prog > 0 || prog == 0) && prog < 70) // 小于70%时,加快进度条更新                    {                        SystemClock.sleep(100);                    }                    else                    // 大于70%时,减慢进度条更新                    {                        SystemClock.sleep(300);                    }                    publishProgress(prog); // 更新进度条                    prog++;                }            }            return null;        }        @Override        protected void onProgressUpdate(Integer... values) {//values是从publishProgress方法传过来的            super.onProgressUpdate(values);            mPb.setProgress(values[0]);        }    }    class ThreadPoolAdapter extends BaseAdapter{        private Context mContext;        private LayoutInflater mInflater;        private int taskcount;        public ThreadPoolAdapter(Context context,int taskCount){            mContext = context;            taskcount = taskCount;            mInflater = LayoutInflater.from(mContext);            mPoolTasks = new ArrayList<>();        }        @Override        public int getCount() {            return taskcount;        }        @Override        public Object getItem(int position) {            return mPoolTasks.get(position);        }        @Override        public long getItemId(int position) {            return position;        }        @Override        public View getView(int position, View convertView, ViewGroup parent) {            if(convertView == null){                convertView = mInflater.inflate(R.layout.list_view_item,null);                PoolTask poolTask = new PoolTask(convertView);                //根据指定的执行器执行任务                poolTask.executeOnExecutor(currentExecutor);                mPoolTasks.add(poolTask);            }            return convertView;        }    }}

效果二(Runnable、ConcurrentLinkedQueue、ConcurrentMap、Future、ExecutorService关联实现)

public class MainActivity extends AppCompatActivity {    //线程池是否处于运行状态    private boolean isRunning = true;    //是否唤醒线程池工作    private boolean isNotify = true;    //在此类中使用同步锁时使用如下lock对象即可,官方推荐的,不推荐直接使用MainActivity.this类型的    private Object lock = new Object();    private Handler mHandler = new Handler() {        @Override        public void handleMessage(Message msg) {            super.handleMessage(msg);            mProgressBar.setProgress(msg.what);        }    };    //任务执行队列    private ConcurrentLinkedQueue<MyRunnable> taskQueue;    //正在等待执行或者已经完成的任务队列,线程安全的(HashMap是线程不安全的)    private ConcurrentHashMap<Future, MyRunnable> taskMap;    //创建一个不限制大小的线程池 此类主要有以下好处 1,以共享的无界队列方式来运行这些线程. 2,执行效率高。    // 3,在任意点,在大多数 nThreads 线程会处于处理任务的活动状态    //4,如果在关闭前的执行期间由于失败而导致任何线程终止,那么一个新线程将代替它执行后续的任务(如果需要)。    private ExecutorService mCachedThreadPool;    private ProgressBar mProgressBar;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        mProgressBar = (ProgressBar) findViewById(R.id.progressBar1);        taskQueue = new ConcurrentLinkedQueue<MyRunnable>();        taskMap = new ConcurrentHashMap<Future, MyRunnable>();        if (mCachedThreadPool == null) {            mCachedThreadPool = Executors.newCachedThreadPool();        }    }    public void click(View view) {        switch (view.getId()) {            case R.id.add:                addTask(new MyRunnable(mHandler));                break;            case R.id.start:                startTask();                break;            case R.id.cancel:                cancelTask();                break;            case R.id.release:                releaseTask();                break;            case R.id.reload:                reloadTask(new MyRunnable(mHandler));                break;        }    }    public void addTask(final MyRunnable myRunnable){        mHandler.sendEmptyMessage(0);        if(mCachedThreadPool == null){            mCachedThreadPool = Executors.newCachedThreadPool();            notifyWork();        }        if(taskMap == null){            taskMap = new ConcurrentHashMap<>();        }        if(taskQueue == null){            taskQueue = new ConcurrentLinkedQueue<>();        }        mCachedThreadPool.execute(new Runnable() {            @Override            public void run() {                taskQueue.offer(myRunnable);//插入一个Runnable到任务队列                notifyWork();            }        });        Toast.makeText(MainActivity.this, "已添加一个新任务到线程池中 !",Toast.LENGTH_SHORT).show();    }    public void startTask(){        if(mCachedThreadPool == null||taskMap == null||taskQueue == null){            return;        }        mCachedThreadPool.execute(new Runnable() {            private MyRunnable mMyRunnable;            @Override            public void run() {                if(isRunning){                    synchronized (lock){                        mMyRunnable = taskQueue.poll();//从线程队列里面取出一个Runnable用来执行                        if(mMyRunnable == null){                            isNotify = true;                        }                    }                    if(mMyRunnable!=null){                        taskMap.put(mCachedThreadPool.submit(mMyRunnable),mMyRunnable);                    }                }            }        });    }    public void cancelTask(){        Toast.makeText(this, "任务被取消", Toast.LENGTH_SHORT).show();        for(MyRunnable mr:taskMap.values()){            mr.setCancelTask(true);        }    }    public void reloadTask(final MyRunnable myRunnable){        mHandler.sendEmptyMessage(0);        if(mCachedThreadPool == null){            mCachedThreadPool = Executors.newCachedThreadPool();            notifyWork();        }        if(taskMap == null){            taskMap = new ConcurrentHashMap<>();        }        if(taskQueue == null){            taskQueue = new ConcurrentLinkedQueue<>();        }        mCachedThreadPool.execute(new Runnable() {            @Override            public void run() {                //插入一个Runnable对象到任务队列                taskQueue.offer(myRunnable);                notifyWork();            }        });        mCachedThreadPool.execute(new Runnable() {            @Override            public void run() {                if(isRunning){                    MyRunnable myRunnable = null;                    synchronized (lock){                        myRunnable = taskQueue.poll();                        if(myRunnable == null){                            isNotify = true;                        }                    }                    if(myRunnable!=null){                        taskMap.put(mCachedThreadPool.submit(myRunnable),myRunnable);                    }                }            }        });    }    public void releaseTask(){        Toast.makeText(this, "释放资源", Toast.LENGTH_SHORT).show();        mHandler.sendEmptyMessage(0);        Iterator<Map.Entry<Future, MyRunnable>> iterator = taskMap.entrySet().iterator();        while (iterator.hasNext()){            Map.Entry<Future,MyRunnable> entry = iterator.next();            Future future = entry.getKey();            if(future == null){                continue;            }            future.cancel(true);            taskMap.remove(future);//移除键对应的值        }        if(mCachedThreadPool!=null){            mCachedThreadPool.shutdown();//关闭执行器        }        mCachedThreadPool = null;        taskMap = null;        taskQueue = null;    }    public void notifyWork(){        synchronized (lock){            if(isNotify){                lock.notifyAll();                isNotify = !isNotify;            }        }    }}

最后给出一篇写的比较好的关于线程池介绍的文章
线程池的使用

0 0
原创粉丝点击