Android中线程池的使用之单例设计模式

开发中只要和网络打交道的基本上我们都会遇到多线程的问题,今天我们就来学习一下

Android中线程池的使用,很多时候我们使用多线程都是new一个Thread来进行子线程的

任务处理:但是这其中牵涉到几个问题:

    (1):线程的创建,销毁等需要巨大的开销

    (2):线程的安全性问题,这个当我们接触稍微大点的项目的时候就会出现

    (3):多个线程不容易管理,比较麻烦等。

1:下面直接上代码:创建一个类专门用来管理线程:

**
 * 本应用的线程管理器,1:首先要做一个池子 2:必须做成单例模式(懒汉),防止创建多个线程,达不到管理效果
 * 3:考虑线程安全问题
 * Created by acer-pc on 2018/6/19.
 */

public class ThreadManager {

 private static ThreadPool mThreadPool;

public static ThreadPool getThreadPool() {
   if (mThreadPool == null) {
      synchronized (ThreadManager.class) {
         if (mThreadPool == null) {
            
            int cpuCount = Runtime.getRuntime().availableProcessors(); // 获取cpu数量,即核数
            int threadCount = cpuCount*2+1; //线程池中线程的个数---cpu核数*2+1--性能最佳

            mThreadPool = new ThreadPool(threadCount,threadCount,1L);
         }
      }
   }
   return mThreadPool;

}

// 线程池---对系统的线程池做的封装
public static class ThreadPool {
   private int corePoolSize;
   private int maximumPoolSize;
   private long keepAliveTime;
  
   private ThreadPoolExecutor executor; // 执行体-->系统底层自带的线程池
   private Runnable r;

   
   public ThreadPool(int corePoolSize, int maximumPoolSize,
         long keepAliveTime) {
      super();
      this.corePoolSize = corePoolSize;
      this.maximumPoolSize = maximumPoolSize;
      this.keepAliveTime = keepAliveTime;
   }
   
   
   
   //1.执行任务
   public void exeute(Runnable r) {
      
      if(executor == null){
      executor = new ThreadPoolExecutor(corePoolSize,
            maximumPoolSize, keepAliveTime, TimeUnit.SECONDS,
            new LinkedBlockingDeque<Runnable>(),
            Executors.defaultThreadFactory(),
            new AbortPolicy());
      // 参数1:corePoolSize核心线程数;参数2:maximumPoolSize最大线程数;参数3:keepAliveTime休息时间;参数4:unit时间单位;参数5:workQueue线程队列;参数6:threadFactory线程工厂;参数7:handler异常处理策略
      }

      
      //线程池执行一个runnable对象,具体运行时机线程池executor底层说了算
      executor.execute(r);
      
   }
   
   //2.取消任务
   public void cancel(Runnable r){
      if(executor != null){
         //从线程未开始的排队队列中移除对象
         executor.getQueue().remove(r);
         
      }
   }
}
}

2:再单独创建一个全局的类(我们就叫APIConfig类吧),用来调用线程池,类中使用如下方法调用:

public static void getDataIntoView(Runnable runnable) {
    ThreadManager.getThreadPool().exeute(runnable);
}

3: 单独再创建一个工具类(我们就叫UIUtils 类吧)来从方便从子线程切换到主线程中去,类中方法如下:

public class UIUtils {

    /**
     * 获取上下文
     */
    public static Context getContext() {
        return MyApplication.getContext();
    }

    /**
     * 获取消息处理器
     */
    public static Handler getHandler() {
        return MyApplication.getHandler();
    }

    /**
     * 获取主线程
     */
    public static int getMainThread() {
        return MyApplication.getMainThreadId();
    }


    ///判断是否运行在主线程//
    public static boolean isRunOnUiThread() {
        int myTid = android.os.Process.myTid();
        if (myTid == getMainThread())
            return true;
        return false;
    }

    public static void runOnUIThread(Runnable r){
        if(isRunOnUiThread()){
            r.run();
        }else{
            getHandler().post(r);//如果是子线程,借助handler让其运行在主线程
        }
    }

    public static void runOnUIThread(Runnable r,long s){
        getHandler().postDelayed(r,s);
    }

    public static String getCurrentProcessName(){
        int pid = android.os.Process.myPid();
        String processName="";
        ActivityManager manager=(ActivityManager)MyApplication.getContext().getSystemService(Context.ACTIVITY_SERVICE);
        for (ActivityManager.RunningAppProcessInfo process:manager.getRunningAppProcesses()){
            if(process.pid == pid){
                processName = process.processName;
            }
        }
        return processName;
    }


}

3:补充一个在自己定义的Application中提供所需的方法:

public class MyApplication extends MultiDexApplication {

    public static Activity activity;
    private static MyApplication application;
    private static Handler handler;
    private static int mainThreadId;
    private Context context;

    @Override
    public void onCreate() {
        super.onCreate();
        application = this;
        context = getApplicationContext();
        handler = new Handler();
        mainThreadId = android.os.Process.myPid();
    }
    
    /**
     * 获取到本应用的对象
     */
    public static MyApplication getApplication(){
        return application;
    }
    /**
     * 获取上下文
     */
    public static Context getContext(){
        return getApplication().getApplicationContext();
    }
    /**
     * 获取消息处理器
     */
    public static Handler getHandler(){
        return handler;
    }
    /**
     * 获取主线程id
     */
    public static int getMainThreadId(){
        return mainThreadId;
    }
    
    @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(base);
        MultiDex.install(this);
    }
    
}

4:使用的时候(在我们需要使用的类中假如初始化数据是用initData()方法)就直接按如下方法调用就可以了:

public void initData() {
    APIConfig.getDataIntoView(new Runnable() {
        @Override
        public void run() {
           //这里做具体的任务在子线程中
           .........................

            UIUtils.runOnUIThread(new Runnable() {
                @Override
                public void run() {
                    //这里回到我们的主线程中来操作
            ...........................
                   
            });
        }
    });
}

5:经过这几步我们就完成了异步加载的整个流程,是不是很简单!

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
Android Studio 使用线程池需要以下步骤: 1. 创建一个线程池对象。可以使用 Executors 类的静态方法来创建线程池对象,例如:`ExecutorService executor = Executors.newFixedThreadPool(3);`,这里创建了一个固定大小为3的线程池。 2. 创建一个实现 Runnable 接口的类,重写 run() 方法,将需要执行的操作放在 run() 方法。 3. 将 Runnable 对象提交给线程池进行执行,可以使用 execute() 方法或 submit() 方法,例如:`executor.execute(new MyRunnable());`,这里将一个 MyRunnable 对象提交给线程池进行执行。 4. 当不需要使用线程池时,需要调用 shutdown() 方法关闭线程池。例如:`executor.shutdown();` 下面是一个完整的示例代码: ``` public class MainActivity extends AppCompatActivity { private ExecutorService executor; private TextView textView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); textView = findViewById(R.id.text_view); // 创建线程池对象 executor = Executors.newFixedThreadPool(3); // 提交任务 executor.execute(new MyRunnable()); executor.execute(new MyRunnable()); executor.execute(new MyRunnable()); } @Override protected void onDestroy() { super.onDestroy(); // 关闭线程池 executor.shutdown(); } private class MyRunnable implements Runnable { @Override public void run() { // 在这里执行需要执行的操作 // 可以更新 UI,但需要使用 runOnUiThread() 方法 runOnUiThread(new Runnable() { @Override public void run() { textView.setText("Hello World"); } }); } } } ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值