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

参照上面的注解,至于线程池中的四种应用,没什么特别要说的.










0 0
原创粉丝点击