SORU
1 Kasım 2010, PAZARTESİ


Çalışan birden fazla aynı anda mümkün değil AsyncTasks?

Aynı anda iki AsyncTasks yapmaya çalışıyorum. (Android 1.5, HTC Hero.) Ancak, yalnızca ilk infaz ediliyor. İşte benim sorunum açıklamak için basit bir parçacık:

public class AndroidJunk extends Activity {
 class PrinterTask extends AsyncTask<String, Void, Void> {
     protected Void doInBackground(String ... x) {
      while (true) {
       System.out.println(x[0]);
       try {
        Thread.sleep(1000);
       } catch (InterruptedException ie) {
        ie.printStackTrace();
       }
      }
        }
    };

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        new PrinterTask().execute("bar bar bar");
        new PrinterTask().execute("foo foo foo");

        System.out.println("onCreate() is done.");
    }
}

Beklediğim çıktı

onCreate() is done.
bar bar bar
foo foo foo
bar bar bar
foo foo foo

Ve benzeri. Ben ne ancak

onCreate() is done.
bar bar bar
bar bar bar
bar bar bar

İkinci AsyncTask asla infaz ediliyor. Eğer idam sırasını değiştirirsem() ifadeleri, sadece foo görev çıktı üretecektir.

Eksik bir şey açık burada ve/veya aptalca bir şey yapıyor muyum? Olası iki AsyncTasks çalıştırmak için aynı anda değil mi?

Edit: söz konusu telefon sorunu descr güncelledim. 1.5, Android çalıştırır anladım buna göre. HTC Hero Android 2.1 ile çalışan bu sorunum yok. Hmmm ...

CEVAP
1 Kasım 2010, PAZARTESİ


AsyncTask doİnBackground eşyalar için çalışan iş parçacığı havuzu bir desen () kullanır. Konu havuzu boyutu sadece AsyncTasks bir grup için 1, hayır paralel hesaplamaları anlamı vardı başlangıçta (erken Android OS sürümleri). Ama daha sonra tamir ettiler ve şimdi çok Boyutu 5 AsyncTasks aynı anda çalışabilir en fazla 5. Ne yazık ki değiştirdikleri şey hatırlamıyorum.

GÜNCELLEME:

Geçerli (2012-01-27) API bu konuda diyor ki:

İlk tanıştırdığında, AsyncTasks seri olarak tek bir arka plan iş parçacığı üzerinde idam edildi. DONUT ile başlayarak, bu iş parçacığı birden fazla görevi paralel olarak çalıştırmak için izin veren bir havuz olarak değiştirilmiştir. PETEK sonra, bu yaygın uygulama hataları paralel yürütme önlemenin tek bir iş parçacığı için geri değiştirmek için planlanmıştır. Eğer gerçekten paralel yürütme istiyorsanız, THREAD_POOL_EXECUTOR; ancak, Yorum yok kullanımı konusundaki uyarıları ile bu yöntemin executeOnExecutor(Vasi, Parametreler...) sürümünü kullanabilirsiniz.

ÇÖREK 3.0 Android 1.6 Android.

GÜNCELLEME: 2

Mar 7 at 1:27 kabuko yorum bakın.

Görünen o ki, bu kişilerin "bir havuzu iş parçacığı veren birden fazla görevleri çalıştırmak için paralel" kullanılır (başlangıç ve bitiş 1.6 3.0 sayıda aynı anda çalışan AsyncTasks bağlı kaç tane görevleri var oldu geçti yürütme zaten, ama yok bitmiş doInBackground() henüz.

Bu test/2.2 beni doğruluyor. Sadece doInBackground() Bir saniye uyumayan özel bir AsyncTask olduğunu varsayalım. AsyncTasks dahili sabit boyutlu bir sıra gecikmiş görevleri depolamak için kullanın. Sıra boyutu varsayılan olarak 10. Eğer bir satırda 15 özel görevler başlarsanız, o zaman ilk 5 ama gerisi serbest bir iş parçacığı için bir kuyrukta bekler doInBackground(), onların girecek. Herhangi bir ilk 5 bitirir, ve böylece bir iş parçacığı serbest olarak, sıradan bir görev icra başlayacak. Bu durumda en fazla 5 görevi aynı anda çalışır. Ancak eğer başlatmak 16 özel görevler bir satır, sonra ilk 5 girer kendi doInBackground(), geri kalan 10 olur içine sıra, ama Ayın 16'sında yeni bir iş parçacığı oluşturulur böylece başlayacağız yürütme hemen. Bu durumda en fazla 6 görevi aynı anda çalışır.

Birçok görevi aynı anda çalıştırmak ne kadar sınırı vardır. Beri AsyncTask kullanan bir iş parçacığı havuzu vasi ile sınırlı maksimum çalışan iş parçacıkları (128) ve gecikmiş görevleri sırası olan sabit bir boyutu 10, eğer sen denemek yürütmek daha 138 özel görevler app kilitlenmesine java.util.concurrent.RejectedExecutionException.

3.0 başlayarak API AsyncTask.executeOnExecutor(Executor exec, Params... params) yöntemi ile özel bir iş parçacığı havuzu uygulamakla kullanmak için izin verir. Bu, örneğin, varsayılan 10 sıra, eğer gecikmiş görevleri boyutunu yapılandırmak için ihtiyacınız olan bir şey değil sağlar.

GÜNCELLEME: 3

Burada görev sayısı ile oynamak için basit bir test uygulaması, vs paralel yürütme seri: https://github.com/vitkhudenko/test_asynctask

GÜNCELLEME: 4(teşekkürler @) bu işaret için penkzhou

4.4 AsyncTask Android başlayarak farklı anlatılır, ne gelen davranırGÜNCELLEME: 2bölüm. 23 ** çok fazla iş parçacığı oluşturma AsyncTask önlemek için.

Daha önce Android 4.4 (API 19) AsyncTask aşağıdaki alanlar vardı:

private static final int CORE_POOL_SIZE = 5;
private static final int MAXIMUM_POOL_SIZE = 128;
private static final BlockingQueue<Runnable> sPoolWorkQueue =
        new LinkedBlockingQueue<Runnable>(10);

Android 4.4 (API 19) yukarıdaki alanları bu değişti

private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
private static final int CORE_POOL_SIZE = CPU_COUNT   1;
private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2   1;
private static final BlockingQueue<Runnable> sPoolWorkQueue =
        new LinkedBlockingQueue<Runnable>(128);

Bu değişiklik, 128 öğeler için sıraya boyutunu artırır ve CPU çekirdek sayısı * 1 2 iş parçacığı sayısı azalır. Uygulamalar hala görevleri aynı sayıda gönderebilirsiniz.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Matus Slovak

    Matus Slovak

    5 Temmuz 2007
  • Rockstar Games

    Rockstar Gam

    17 ŞUBAT 2006
  • TheRightTire

    TheRightTire

    14 EKİM 2009