<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      奔跑的肥豬

      導航

      AsyncTask RejectedExecutionException 小結

      在使用Asynctask時,相信有些朋友會遇到以下RejectedExecutionException:

      Java.util.concurrent.RejectedExecutionException: Task android.os.AsyncTask$3@e3a9753 rejected from java.util.concurrent.ThreadPoolExecutor@63fe890[Running, pool size = 9, active threads = 9, queued tasks = 128, completed tasks = 0]
      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416)
      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
      at android.app.ActivityThread.-wrap11(ActivityThread.java)
      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
      at android.os.Handler.dispatchMessage(Handler.java:102)
      at android.os.Looper.loop(Looper.java:148)
      at android.app.ActivityThread.main(ActivityThread.java:5417)
      at java.lang.reflect.Method.invoke(Native Method)
      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

      到底是什么原理導致以上RuntimeException呢? 讓我們一起研讀源碼來一探究竟。

      首先,可以使用以下代碼來制造上面的Exception:

      package com.breakmedia.interview.asyncTask;
      
      import android.os.AsyncTask;
      import android.util.Log;
      
      public class AsyncPool {
      
          private static int TASK_NUMBER = 138;
          private static final String TAG = "jeff";
      
          public void doTask() {
              for (int i = 0; i <= TASK_NUMBER; i++) {
                  String task = "task@ " + i;
                  Log.d(TAG, "put " + task);
                  MyAsyncTask myAsyncTask = new MyAsyncTask(task);
                  myAsyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, 0);
              }
          }
      
          static class MyAsyncTask extends AsyncTask<Integer, Integer, Integer> {
              private static int SLEEP_TIME = 2000;
              private String name;
      
              public MyAsyncTask(String name) {
                  this.name = name;
              }
      
              protected Integer doInBackground(Integer... arg0) {
                  Log.d(TAG, "start .." + name
                          + " thread id: " + Thread.currentThread().getId()
                          + " thread name: " + Thread.currentThread().getName());
                  try {
                      Thread.sleep(SLEEP_TIME);
                  } catch (Exception e) {
                      Log.d(TAG, "", e);
                  }
                  return 0;
              }
          }
      }

      需要解釋的是,我用的CPU 是四核,所以對應的 MAXIMUM_POOL_SIZE 為9, 

      private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;

      而在AsyncTask 內部有一個static 的變量 ThreadPoolExecutor, 其 workQuene 為容量為128的 LinkedBlockingQueue:

      private static final BlockingQueue<Runnable> sPoolWorkQueue =
                  new LinkedBlockingQueue<Runnable>(128);
      
          /**
           * An {@link Executor} that can be used to execute tasks in parallel.
           */
          public static final Executor THREAD_POOL_EXECUTOR;
      
          static {
              ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
                      CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE_SECONDS, TimeUnit.SECONDS,
                      sPoolWorkQueue, sThreadFactory);
              threadPoolExecutor.allowCoreThreadTimeOut(true);
              THREAD_POOL_EXECUTOR = threadPoolExecutor;
          }

       

      綜上所述,如果按照  myAsyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, 0);

      調用,如果Task_NUMBER 設置為138,應該會出現RejectException, 結果是不是和預想一樣的呢? 運行程序,如果得到一樣的RuntimeException

      java.util.concurrent.RejectedExecutionException: Task android.os.AsyncTask$3@63fe890 rejected from java.util.concurrent.ThreadPoolExecutor@1721589[Running, pool size = 9, active threads = 9, queued tasks = 128, completed tasks = 0]
                                                           at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416)
                                                           at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
                                                           at android.app.ActivityThread.-wrap11(ActivityThread.java)
                                                           at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
                                                           at android.os.Handler.dispatchMessage(Handler.java:102)
                                                           at android.os.Looper.loop(Looper.java:148)
                                                           at android.app.ActivityThread.main(ActivityThread.java:5417)
                                                           at java.lang.reflect.Method.invoke(Native Method)
                                                           at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                                                           at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
                                                        Caused by: java.util.concurrent.RejectedExecutionException: Task android.os.AsyncTask$3@63fe890 rejected from java.util.concurrent.ThreadPoolExecutor@1721589[Running, pool size = 9, active threads = 9, queued tasks = 128, completed tasks = 0]
                                                           at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2014)
                                                           at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:794)
                                                           at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1340)
                                                           at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:607)
                                                           at com.breakmedia.interview.asyncTask.AsyncPool.doTask(AsyncPool.java:16)
                                                           at com.ryg.chapter_11.MainActivity.onCreate(MainActivity.java:91)
                                                           at android.app.Activity.performCreate(Activity.java:6237)
                                                           at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
                                                           at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
                                                           at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476) 
                                                           at android.app.ActivityThread.-wrap11(ActivityThread.java) 
                                                           at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344) 
                                                           at android.os.Handler.dispatchMessage(Handler.java:102) 
                                                           at android.os.Looper.loop(Looper.java:148) 
                                                           at android.app.ActivityThread.main(ActivityThread.java:5417) 
                                                           at java.lang.reflect.Method.invoke(Native Method) 
                                                           at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
                                                           at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:61604-25 13:55:12.788 763-833/system_process E/Surface: getSlotFromBufferLocked: unknown buffer: 0xde3024d0

      同理,如果我將

       private static int TASK_NUMBER = 136;

      是不是程序正常運行呢?個人測試下來,沒有碰到crash。

      04-25 14:06:21.013 11266-11281/com.ryg.chapter_11 D/jeff: start ..task@ 121 thread id: 277 thread name: AsyncTask #1
      04-25 14:06:22.959 11266-11285/com.ryg.chapter_11 D/jeff: start ..task@ 122 thread id: 281 thread name: AsyncTask #5
      04-25 14:06:22.960 11266-11289/com.ryg.chapter_11 D/jeff: start ..task@ 124 thread id: 285 thread name: AsyncTask #9
      04-25 14:06:22.961 11266-11283/com.ryg.chapter_11 D/jeff: start ..task@ 123 thread id: 279 thread name: AsyncTask #3
      04-25 14:06:22.970 11266-11288/com.ryg.chapter_11 D/jeff: start ..task@ 125 thread id: 284 thread name: AsyncTask #8
      04-25 14:06:22.970 11266-11286/com.ryg.chapter_11 D/jeff: start ..task@ 126 thread id: 282 thread name: AsyncTask #6
      04-25 14:06:22.996 11266-11284/com.ryg.chapter_11 D/jeff: start ..task@ 127 thread id: 280 thread name: AsyncTask #4
      04-25 14:06:22.996 11266-11282/com.ryg.chapter_11 D/jeff: start ..task@ 128 thread id: 278 thread name: AsyncTask #2
      04-25 14:06:22.996 11266-11287/com.ryg.chapter_11 D/jeff: start ..task@ 129 thread id: 283 thread name: AsyncTask #7
      04-25 14:06:23.053 11266-11281/com.ryg.chapter_11 D/jeff: start ..task@ 130 thread id: 277 thread name: AsyncTask #1
      04-25 14:06:25.001 11266-11285/com.ryg.chapter_11 D/jeff: start ..task@ 131 thread id: 281 thread name: AsyncTask #5
      04-25 14:06:25.001 11266-11283/com.ryg.chapter_11 D/jeff: start ..task@ 132 thread id: 279 thread name: AsyncTask #3

      讓我們看看AsyncTask為什么到達閾值時,這個RuntimeException的調用過程:

      ThreadPoolExecutor 的構造函數如下:

      public ThreadPoolExecutor(int corePoolSize,
                                    int maximumPoolSize,
                                    long keepAliveTime,
                                    TimeUnit unit,
                                    BlockingQueue<Runnable> workQueue,
                                    ThreadFactory threadFactory) {
              this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
                   threadFactory, defaultHandler);
          }

      其中defaultHandler的實現如下:

      private static final RejectedExecutionHandler defaultHandler = new AbortPolicy();

      其中AbortPolicy的源碼如下:

      /**
           * A handler for rejected tasks that throws a
           * {@code RejectedExecutionException}.
           */
          public static class AbortPolicy implements RejectedExecutionHandler {
              /**
               * Creates an {@code AbortPolicy}.
               */
              public AbortPolicy() { }
      
              /**
               * Always throws RejectedExecutionException.
               *
               * @param r the runnable task requested to be executed
               * @param e the executor attempting to execute this task
               * @throws RejectedExecutionException always
               */
              public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
                  throw new RejectedExecutionException("Task " + r.toString() +
                                                       " rejected from " +
                                                       e.toString());
              }
          }

      所以大家現在應該知道 RejectedExecutionException 是如何產生的吧。

      最后需要強調一下,其實google很早就意識到這個問題,所以默認的方式是

      myAsyncTask.execute(0);

      而不是

      myAsyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, 0);

      使用的默認方式,不會出現RejectedExecutionException,即使 TASK_NUMBER = 500, 不信的同志可以自己試驗一下。究其原因,可以看以下代碼:

       @MainThread
          public final AsyncTask<Params, Progress, Result> execute(Params... params) {
              return executeOnExecutor(sDefaultExecutor, params);
          }
      private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;
      private static class SerialExecutor implements Executor {
              final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>();
              Runnable mActive;
      
              public synchronized void execute(final Runnable r) {
                  mTasks.offer(new Runnable() {
                      public void run() {
                          try {
                              r.run();
                          } finally {
                              scheduleNext();
                          }
                      }
                  });
                  if (mActive == null) {
                      scheduleNext();
                  }
              }
      
              protected synchronized void scheduleNext() {
                  if ((mActive = mTasks.poll()) != null) {
                      THREAD_POOL_EXECUTOR.execute(mActive);
                  }
              }
          }

      從以上代碼可以看出,因為 execute 和  scheduleNext 都加了鎖,線程應該是串行執行,而不是并行執行,THREAD_POOL_EXECUTOR.execute(mActive) 每次執行一個,當然不會到達峰值(137)。但是由于是串行執行,又會帶來一個新的問題,有人用AsyncTask加載圖片的時候特別慢,具體細節,請參考如下 博客:

      Android實戰技巧:深入解析AsyncTask

       

      posted on 2017-04-25 15:29  布兜兜  閱讀(3098)  評論(0)    收藏  舉報

      主站蜘蛛池模板: 精品偷自拍另类精品在线| 90后极品粉嫩小泬20p| 艳妇乳肉豪妇荡乳在线观看| 国产偷国产偷亚洲高清日韩| 亚洲va久久久噜噜噜久久狠狠| 激情 小说 亚洲 图片 伦| 亚洲精品国产综合麻豆久久99| 九九热视频在线观看精品| 亚洲产在线精品亚洲第一站一| 国产精品线在线精品| 九九热在线精品视频首页| 高清精品一区二区三区| 国产精品一区 在线播放| 94人妻少妇偷人精品| 欧美无人区码suv| 日韩成人一区二区三区在线观看| 噜噜噜噜私人影院| 成人aⅴ综合视频国产| 国产精品一区二区AV| 久久精品丝袜高跟鞋| 日韩有码中文在线观看| 国产精品久久久久久福利69堂| 国产av不卡一区二区| 成年午夜无码av片在线观看| 国产美女自慰在线观看| 日韩一区在线中文字幕| 少妇高潮尖叫黑人激情在线| 宅男久久精品国产亚洲av麻豆| 亚洲欧洲日韩国内精品| 亚洲中少妇久久中文字幕| 亚洲亚洲人成综合网络| 性做久久久久久久| 色吊丝二区三区中文字幕| 波多野结衣免费一区视频| 国偷自产一区二区三区在线视频 | 国产AV福利第一精品| 国产美女久久久亚洲综合 | 亚洲精品成人区在线观看| 亚洲中文字幕精品第三区| 国产成人午夜福利院| 莆田市|