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都有一个新的线程来执行,即并发执行。
下一篇:
软件开发学什么编程语言好