Android 线程池 工作调度

我想网上面一大堆关于线程池的文章和资料,这里面介绍一些需要注意和最好能够了解的部分.

一般使用线程池就会想到类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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值