Android 线程池 工作调度
来源:互联网 发布:cf出现网络异常 编辑:程序博客网 时间:2024/06/12 23:06
我想网上面一大堆关于线程池的文章和资料,这里面介绍一些需要注意和最好能够了解的部分.
一般使用线程池就会想到类ExecutorService和Executors
不知道是否有人看过他们的源代码,他们的关系如下:
public interface ExecutorService extends Executor
当然可以知道Executors也是个接口:
public interface Executor {
这个里面个人觉得需要注意ExecutorService.java中的
<T> Future<T> submit(Callable<T> task);
其中重点的Future类:
public interface Future<V> {
线程池管理着一堆的线程,如何获取这些线程运行状态呢?那么就需要了解Future类的作用了.我个人觉得这个类的作用主要是"占坑",当线程被submit的时候,返回一个Future对象,通过获取这个Future对象,并且调用其get()方法来获取线程的基本运行状态.虽然它能够让人知道线程池中的线程运行状态,但是由于这个状态是通过反馈回来的,如果线程池中的线程没有运行完,它就迟迟不会受到反馈信息,如果没有收到反馈信息,它就会阻塞它所在的线程,如果放在UI线程中,那么一旦运行,那么UI线程就会卡住,所以一般最好是放在异步线程中,比如说向服务确认身份认证,那么就要一直等待服务器反馈正确信息后,才能够执行向服务器请求的其他工作.
private void futureForPool(){ mPool=Executors.newFixedThreadPool(10); Future<String> future=mPool.submit(new Callable<String>() { @Override public String call() throws Exception { Thread.sleep(2500); Log.i(TAG,"future callback !"); return "zhibao.liu !"; } }); try { String msg=future.get().toString(); Log.i(TAG,"future msg : "+msg); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } }
另外一个FutureTask类:
public class FutureTask<V> implements RunnableFuture<V> {
public interface RunnableFuture<V> extends Runnable, Future<V> {
可以看出它也是Future机制的.
private void futureTaskForPool(){ mPool=Executors.newFixedThreadPool(10); FutureTask<String> mft=new FutureTask<String>(new Callable<String>() { @Override public String call() throws Exception { Thread.sleep(2500); Log.i(TAG,"FutureTask work !"); return null; } }); mPool.execute(mft); try { mft.get(500, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { boolean iswork=mft.isDone(); if(!iswork){ Log.i(TAG,"FutureTask is still working !"); } mft.cancel(true);// e.printStackTrace(); } catch (ExecutionException e) { boolean iswork=mft.isDone(); if(!iswork){ Log.i(TAG,"FutureTask is still working !"); } mft.cancel(true);// e.printStackTrace(); } catch (TimeoutException e) { boolean iswork=mft.isDone(); if(!iswork){ Log.i(TAG,"FutureTask is still working !"); } mft.cancel(true);// e.printStackTrace(); }finally { mPool.shutdown(); } Log.i(TAG,"FutureTask i : finish !"); }下面的需要注意:
mft.get(500, TimeUnit.MILLISECONDS);
线程中的任务需要在500ms时间的时候给出反馈,无论事情是否做完,如果事情还没有做完将会报出timeout异常,在处理异常中可以继续判断事情是否做完,如果没有做完,我们将其抛弃:
mft.cancel(true);
工作将不再继续执行.
就像食品有效日期一样,如果在有效日内,就可以继续食用,如果超出指定的有效日,就没有必要继续食用了.事情也是这样,有些事情只有在规定的时间内完成才有意义,如果超出了时间就没什么意义了.
下面给出整个工程源码:
package org.durian.durianexecutors;import android.os.Bundle;import android.support.v7.app.ActionBarActivity;import android.util.Log;import android.view.Menu;import android.view.MenuItem;import android.view.View;import android.widget.Button;import java.util.concurrent.Callable;import java.util.concurrent.ExecutionException;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.Future;import java.util.concurrent.FutureTask;import java.util.concurrent.ScheduledExecutorService;import java.util.concurrent.ThreadFactory;import java.util.concurrent.TimeUnit;import java.util.concurrent.TimeoutException;public class DurianMainActivity extends ActionBarActivity implements View.OnClickListener { private final static String TAG="DurianMainActivity"; private Button mCachePoolButton; private Button mFixPoolButton; private Button mSchedulePoolButton; private Button mSinglePoolButton; private Button mFutureButton; private Button mFactoryButton; private ExecutorService mPool; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.durian_main); mCachePoolButton=(Button)findViewById(R.id.cachepool); mCachePoolButton.setOnClickListener(this); mFixPoolButton=(Button)findViewById(R.id.fixpool); mFixPoolButton.setOnClickListener(this); mSchedulePoolButton=(Button)findViewById(R.id.schedulepool); mSchedulePoolButton.setOnClickListener(this); mSinglePoolButton=(Button)findViewById(R.id.singlepool); mSinglePoolButton.setOnClickListener(this); mFutureButton=(Button)findViewById(R.id.future); mFutureButton.setOnClickListener(this); mFactoryButton=(Button)findViewById(R.id.fixpoolforfactory); mFactoryButton.setOnClickListener(this); } @Override public void onClick(View v) { int id=v.getId(); switch (id){ case R.id.future: futureTaskForPool(); break; case R.id.cachepool: cachePoolForThread(); break; case R.id.fixpool: fixPoolForThread(); break; case R.id.schedulepool: schedulePoolForThread(); break; case R.id.singlepool: singlePoolForThread(); break; case R.id.fixpoolforfactory: fixPoolForFactoryThread(); break; default: break; } } private int count=0; private void futureForPool(){ mPool=Executors.newFixedThreadPool(10); Future<String> future=mPool.submit(new Callable<String>() { @Override public String call() throws Exception { Thread.sleep(2500); Log.i(TAG,"future callback !"); return "zhibao.liu !"; } }); try { String msg=future.get().toString(); Log.i(TAG,"future msg : "+msg); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } } private void futureTaskForPool(){ mPool=Executors.newFixedThreadPool(10); FutureTask<String> mft=new FutureTask<String>(new Callable<String>() { @Override public String call() throws Exception { Thread.sleep(2500); Log.i(TAG,"FutureTask work !"); return null; } }); mPool.execute(mft); try { mft.get(500, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { boolean iswork=mft.isDone(); if(!iswork){ Log.i(TAG,"FutureTask is still working !"); } mft.cancel(true);// e.printStackTrace(); } catch (ExecutionException e) { boolean iswork=mft.isDone(); if(!iswork){ Log.i(TAG,"FutureTask is still working !"); } mft.cancel(true);// e.printStackTrace(); } catch (TimeoutException e) { boolean iswork=mft.isDone(); if(!iswork){ Log.i(TAG,"FutureTask is still working !"); } mft.cancel(true);// e.printStackTrace(); }finally { mPool.shutdown(); } Log.i(TAG,"FutureTask i : finish !"); } private void cachePoolForThread(){ mPool=Executors.newCachedThreadPool(); count=0; for(int i=0;i<20;i++){ Thread thread=new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(2500); Log.i(TAG,"cachePoolForThread i : "+count++); } catch (InterruptedException e) { e.printStackTrace(); } } }); mPool.execute(thread); } } private void fixPoolForThread(){ mPool=Executors.newFixedThreadPool(10); count=0; for(int i=0;i<10;i++){ Thread thread=new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(1500); Log.i(TAG,"fixpool i="+count++); } catch (InterruptedException e) { e.printStackTrace(); } } }); Future<String> future=mPool.submit(new Callable<String>() { @Override public String call() throws Exception { Thread.sleep(500); Log.i(TAG,"future callback !"); return "zhibao.liu !"; } }); try { String msg=future.get().toString(); Log.i(TAG,"future msg : "+msg); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } mPool.execute(thread); Future<String> m=mPool.submit(new Runnable() { @Override public void run() { try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } Log.i(TAG,"future callback !"); } },"durian from zhibao.liu"); try { Log.i(TAG,"future msg : "+m.get().toString()); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } } } private void fixPoolForFactoryThread(){ count=0; /* * ThreadFactory : 作用 * <1> : 设置线程池中线程属性 * <2> : 代码debug * <3> : 异常捕获 * */ mPool=Executors.newFixedThreadPool(10, new ThreadFactory() { @Override public Thread newThread(Runnable runable) { Thread t=new Thread(runable); t.setDaemon(true); t.setPriority(Thread.MAX_PRIORITY); return t; } }); for (int i=0;i<10;i++){ mPool.execute(new Runnable() { @Override public void run() { try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } Log.i(TAG,"fixPoolForFactoryThread work : "+count++); } }); } } private void schedulePoolForThread(){ ScheduledExecutorService schedule=Executors.newScheduledThreadPool(10); count=0; for (int i=0;i<1;i++){ Log.i(TAG,"schedule work ..."); schedule.schedule(new Runnable() { @Override public void run() { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } Log.i(TAG,"schedule work after 1000 delays : "+count++); } },3000,TimeUnit.MILLISECONDS); } } private void singlePoolForThread(){ mPool=Executors.newSingleThreadExecutor(); count=0; for (int i=0;i<10;i++){ mPool.execute(new Runnable() { @Override public void run() { try { Thread.sleep(2500); } catch (InterruptedException e) { e.printStackTrace(); } Log.i(TAG,"single work in the same thread : "+count++); } }); } }}
布局文件:
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="org.durian.durianexecutors.DurianMainActivity"> <Button android:id="@+id/future" android:text="future mode" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <Button android:id="@+id/cachepool" android:text="newCachedThreadPool" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <Button android:id="@+id/fixpool" android:text="newFixedThreadPool" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <Button android:id="@+id/schedulepool" android:text="newScheduledThreadPool" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <Button android:id="@+id/singlepool" android:text="newSingleThreadExecutor" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <Button android:id="@+id/fixpoolforfactory" android:text="fixPoolForFactory" android:layout_width="wrap_content" android:layout_height="wrap_content" /></LinearLayout>
我们需要注意的是newSingleThreadExecutor返回的对象,这个我个人的理解是分配的N件事情,但是N件事情都是在同一个线程中完成的:从下面可以看出N件事情只在同一个线程中完成
Thread 1是app的主线程,Thread 6是虚拟机中的.
从Thread 28才是,只看见一个吧,下面给个cache的参照:从下面图中可以看出,N件事在N个线程中执行:
另外附加了一个FactoryThread
private void fixPoolForFactoryThread(){ count=0; /* * ThreadFactory : 作用 * <1> : 设置线程池中线程属性 * <2> : 代码debug * <3> : 异常捕获 * */ mPool=Executors.newFixedThreadPool(10, new ThreadFactory() { @Override public Thread newThread(Runnable runable) { Thread t=new Thread(runable); t.setDaemon(true); t.setPriority(Thread.MAX_PRIORITY); return t; } }); for (int i=0;i<10;i++){ mPool.execute(new Runnable() { @Override public void run() { try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } Log.i(TAG,"fixPoolForFactoryThread work : "+count++); } }); } }
参照上面的注解,至于线程池中的四种应用,没什么特别要说的.
- Android 线程池 工作调度
- Android线程调度机制
- Android 中的线程调度
- Android线程调度机制
- Android 中的线程调度
- Android JobScheduler/JobService 工作调度
- 调度线程池
- 任务调度线程池
- Android 工作线程
- java 线程池优先级调度
- libuv 线程池的调度
- Android中的volley_7_网络调度线程NetworkDispatcher
- Android中的volley_8_缓存调度线程CacheDispatcher
- Android 中的线程是如何调度
- Android Rxjava学习三----线程调度
- 线程调度
- 线程调度
- 线程调度
- HDU 2438 Turn the corner
- Python字典的json格式化处理
- DZNEmptyDataSet,优秀的空白页或者出错页封装
- 69. Sqrt(x)
- nginx在windows下配置反向代理
- Android 线程池 工作调度
- codeforces 614B
- android monkey测试
- 异步套接字实现
- 带大家一步一步的封装一个聊天键盘
- [实战] 用数人云,部署弹性 ELK 集群就五步
- apache多站点配置
- 架构一个后台管理系统的技术所需要的技术
- STL_算法_逆转(reverse,reverse_copy)