线程池的使用(三)
来源:互联网 发布:办公室饿 知乎 编辑:程序博客网 时间: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
- 线程池的使用(三)
- 线程学习 (三) 线程池的使用
- Java 并发编程之线程池的使用 (三)
- Java 并发编程之线程池的使用 (三)
- JAVA学习笔记之多线程专题(三):线程池的使用
- 线程池的使用
- 线程池的使用
- 线程池的使用
- 线程池的使用
- 线程池的使用
- 线程池的使用
- 线程池的使用
- 线程池的使用
- 线程池的使用
- 线程池的使用
- 线程池的使用
- 线程池的使用
- 线程池的使用
- JavaScript表达式&运算符
- 【C#反射-动态创建对象】
- Map合并
- CI框架中的开启调试模式
- 长方柱体 2
- 线程池的使用(三)
- 简易版 用户注册(Struts2)
- centos下vim的安装与配置
- Hadoop2.4.1 RPC实现的底层原理(一)
- poj——1275 Cashier Employment 差分约束系统
- The charactor bring the weapon
- 专业贴膜技术知识
- spring-jpa
- 嵌入式系统开发学习(1)