2011-09-14 15 views
4

非同期タスクの実行中に次々に実行される実行可能キューを実装しようとしています(キュー内の次のキューが実行されることを意味します)。私は、これらの実行可能ファイルと実行可能ファイルそのものを管理するためのマネージャを作成しました。私はその後、非同期タスクの最初のタスクを取得し、それがキューを介して実行されることを期待して実行しますが、最初の実行可能ファイルを2回実行するだけです。誰かが私が働いているコードを教えてくれますか、助けになるかもしれない例を教えてください。実行ファイルのキューを実装する方法

public class ConnectionManager { 

    public static final int MAX_CONNECTIONS = 15; 

    private ArrayList<Runnable> active = new ArrayList<Runnable>(); 
    private ArrayList<Runnable> queue = new ArrayList<Runnable>(); 

    private static ConnectionManager instance; 

    public static ConnectionManager getInstance() { 
     if (instance == null) 
      instance = new ConnectionManager(); 
     return instance; 
    } 

    public void push(Runnable runnable) { 
     queue.add(runnable); 
     if (active.size() < MAX_CONNECTIONS) 
      startNext(); 
    } 

    private void startNext() { 
     if (!queue.isEmpty()) { 
      Runnable next = queue.get(0); 
      queue.remove(0); 
      active.add(next); 

      Thread thread = new Thread(next); 
      thread.start(); 
     } 
    } 

    public void didComplete(Runnable runnable) { 
     active.remove(runnable); 
     startNext(); 
    } 
} 

public class Task implements Runnable { 
    Context con; 
    String xmlFile; 
    File taskFile; 
    String Id; 

    public void create(Context context, String xml, File task, String id) { 
     this.con = context; 
     this.xmlFile = xml; 
     this.taskFile = task; 
     this.Id = id; 
     ConnectionManager.getInstance().push(this); 
    } 

    @Override 
    public void run() { 
     User.SendTask(con, xmlFile, taskFile, Id); 

     ConnectionManager.getInstance().didComplete(this); 
    } 

答えて

2

私のアプリの中で非常に似たようなことをやっています。私はそれをきれいに保つために、キューにデータを入れ、実行するスレッドを入れないようにしています。私は実行のために単一のAsyncTaskを使用します(これは、システムが割り当てるスレッドプールから取得します...あなたのための管理を容易にするかもしれません)。そして、doInBackgroundメソッドでは、データをキューから取り出し、そして、onPostExecuteで再び私のエントリーメソッドを呼び出します。

2

これを自分で作成する必要はありません。ThreadPoolExecutorを使用してください。 minPoolのサイズが1で、プールの最大サイズが15であるものを作成してください。すべて設定する必要があります。

+0

実行可能オブジェクトが10億を超えるとどうなりますか? – User3

2

なぜArrayListsの代わりにQueueを使用しないのですか?それはここでよりうまく収まるでしょう。

1

ArrayListはスレッドセーフではありませんが、スレッド化で使用しています。このように、お互いのやり方が違ってきます。おそらく起こっていることは次のとおりです。

  • プッシュをさまざまなランナブルで呼び出します。 addメソッドはこれらのすべてで同時にいくつか呼び出されますが、addはスレッドセーフではないので、最初のものは追加を終了する前に追加を開始しないので、キューには1つのrunnableで終わるだけです。

  • StartNextは同時に複数回と呼ばれます。一方のスレッドは "next = queue.Get()"を実行しますが、別のスレッドは、最初のスレッドがそのアイテムをキューから削除する前に "next = queue.Get()"も呼び出すため、両方のスレッドが処理を終了します同じ実行可能。

あなたは、使用するスレッドセーフオブジェクトを検索、またはミューテックスのいくつかの種類/さまざまなスレッドが互いの邪魔にならないようにロック機構を追加するいずれかが必要になります。

関連する問題