Java 多线程通信 AsyncTask.executeOnExecutor并发深入解析

理解多线程通信

工人A往水桶中倒水、工人B从水桶中取水,只有互相交流才能使得水桶中的水不至于溢出或无水,把两个工人比作线程,线程A往集合中添加元素,线程B往集合中取出元素,就需要通过多线程通信进行协调而有序进行

等待/唤醒机制

    wait(): 让线程处于冻结状态(停止取水)。线程中对象获得线程锁后可执行该方法 内置锁:java对象都可以用做实现同步的锁,这些锁为内置锁。
线程进入同步代码块或方法的时候会自动获得该锁,在退出同步代码块或方法时会释放该锁。获得内置锁的唯一途径就是进入这个锁的保护的同步代码块或方法。
synchronized (obj) {
          
   
    while (<condition)
        obj.wait();// 停止取水
}

// 通过lock()接口获取隐式锁
provite void synchroized method(){
          
   
...
Lock l = ...; 
l.lock();// 阻止取水
}
    notify():唤醒线程池中一个线程(任意)。如果对象调用了notify方法就会通知某个(正在等待这个对象的控制权的)线程可以继续运行。 notifyAll():唤醒线程池中的所有线程。如果对象调用了notifyAll方法就会通知所有等待这个对象控制权的线程继续运行。
{
          
   
     obj = value; // 加水
     obj.notify();// 请继续取水
}
    lock():获取锁。 unlock():释放锁。 Condition接口:替代了Object中的wait notify notifyAll方法。 将这些监视器方法单独进行了封装,变成Condition监视器对象。 可以任意锁进行组合。 await(); signal(); signalAll();

线程池

public static ThreadPoolExecutor mAppThreadPool;  // 应用线程池
	/**
     * 初始化线程池
     */
    private void initThreadPool() {
          
   

        // 根据CPU的核心数获取最佳核心线程数
        int corePoolSize = Runtime.getRuntime().availableProcessors() * 4 + 1;
        // 线程池的最大线程数
        int maxPoolSize = corePoolSize * 4;
        LinkedBlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<>();
        // 拒绝策列
        ThreadPoolExecutor.CallerRunsPolicy handler = new ThreadPoolExecutor.CallerRunsPolicy();
        mAppThreadPool = new ThreadPoolExecutor(corePoolSize, maxPoolSize,
                10, TimeUnit.SECONDS, workQueue,
                Executors.defaultThreadFactory(), handler);
        // 允许核心线程池超时回收
        mAppThreadPool.allowCoreThreadTimeOut(true);

    }
	/**
     * 获取全局线程池
     * @return
     */
    public static ExecutorService getThreadPool(){
          
   
        return mAppThreadPool;
    }

AyncTask实现异步任务线程池

AsyncTask mTask = new AsyncTask();
mTask .executeOnExecutor(AppUtils.getThreadPool(),task);

executeOnExecutor(Executor exec, Object… params),该方法接受2个参数,第一个是Executor,第二个是任务参数。Executor主要由四 种类型newCachedThreadPool,newFixedThreadPool,newScheduledThreadPool,newSingleThreadExecutor

executeOnExecutor是多线程的,即使传入Executor规定为单线程

asyncTask.executeOnExecutor(Executors.newFixedThreadPool(1), task); asyncTask.executeOnExecutor(Executors.newSingleThreadExecutor, task); asyncTask.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, task);和 asyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, task);一样是多线程并发执行的,程 序在每次调用asyncTask.executeOnExecutor(Executors.newFixedThreadPool(2), task)时会获取一个新的Executor对 象,这个对象内的线程只执行对应的task,所以无论哪种情况每个task都有一个新的线程来执行,即并发执行。

经验分享 程序员 微信小程序 职场和发展