2012-01-05 10 views
2

私はHttpClientでスイングアプリケーションを作成しています。新しいダウンロードを開始する前に1分待たなければならないのでダウンロードリストを作成する方法が必要です。Javaのスレッド待ちリスト

スレッドの待機リスト(ダウンロード)を作成したいと思います。 私は、時間パラメータをとり、スレッドのリストを含むクラスを持っていて、リストにスレッドを追加すると、実行中のスレッドがないと起動します。そうでなければ、それはそのターンを待つ。

これを実行するツールはありますか?

ありがとうございました。

+0

タスク/スレッドを追加した直後に開始する予定がある場合は、どのような時間パラメータですか? @β_ɛƨнǤʋяʋиAsは、複数のスレッドを必要とせず、スレッド化された単一のタスク実行プログラム(Executors.newSingleThreadExecutor())がそのジョブを実行するように見えます。 – Vlad

+0

実行中のスレッドがなく、最後のスレッドがx秒前に終了した場合にのみ、スレッドはすぐに開始されます – DnBase

答えて

0

それは多分あります最高の解決策ではありませんが、ここで私はJohn Vintの答えに感謝しています。それが他の人を助けることを願っています。

package tests; 

import java.util.concurrent.ExecutorService; 
import java.util.concurrent.Executors; 
import java.util.concurrent.TimeUnit; 


public class RunnableQueue 
{ 
    private long waitTime; 
    private TimeUnit unit; 

    ExecutorService e; 

    public RunnableQueue(long waitTime, TimeUnit unit) { 
     e = Executors.newSingleThreadExecutor(); 

     this.waitTime = waitTime; 
     this.unit = unit; 
    } 

    public void submitTask(final Runnable r){ 
     e.submit(new Runnable(){ 
      public void run(){ 
       Thread t = new Thread(r); 
       t.start(); 

       try { 
       t.join(); 
       Thread.sleep(unit.toMillis(waitTime)); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
      } 
     }); 
    } 

    public static void main(String[] args) { 
     RunnableQueue runQueue = new RunnableQueue(3, TimeUnit.SECONDS); 

     for(int i=1; i<11; i++) 
     { 
      runQueue.submitTask(new DownloadTask(i)); 
      System.out.println("Submitted task " + i); 
     } 

    } 
} 
0

内蔵のExecutorServiceを使用できます。タスクをRunnableとしてキューイングすると、利用可能なスレッドで実行されます。あなたは(あなたがそれを開始する前に、時間の必要量を待っていることを保証するために、各Runnablerunメソッドの開始時に人工Thread.sleepを追加することができnewFixedThreadPool(1);

ExecutorService executor = Executors.newFixedThreadPool(1); 

を使用していない時間に実行するだけで、単一のタスクをしたい場合最もエレガントな選択、私が知っている)。

1

私は、これが問題について間違ったやり方であると思います。もう少し論理的なやり方は、ジョブキューに追加される「ダウンロードジョブ」オブジェクトを作成することです。 TimerTaskを作成し、1分ごとにこの「キュー」に問い合わせ、Runnable/Callableのジョブを受け取り、ExecutorServiceに送信してください。

+0

これはまさに最初の考えでした。アップボーニング。 – Perception

3

はい。 ScheduledExecutorServiceExecutors.newScheduledThreadPool(corePoolSize)で固定長のサービスを作成することができます。あなたは時間を待つためにタスクを送信する準備ができているときだけでタスクが提出されている時から1分後に起動します。ここScheduledExecutorService.schedule

ScheduledExecutorService e = Executors.newScheduledThreadPool(10) 
private final long defaultWaitTimeInMinutes = 1; 
public void submitTaskToWait(Runnable r){ 
    e.schedule(r, defaultWaitTimeInMinutes, TimeUnit.MINUTES); 
} 

に提出してください。あなたの最後のポイントに対処する。現在タスクがダウンロードされている場合(この構成では、10個のタスクがダウンロードされていることを意味します)、1分後に実行された実行可能ファイルは、他のダウンロードが完了するまで待機する必要があります。

これは設計時のやり方から少しずれていることに注意してください。新しいタスクごとに新しいスレッドを作成するのではなく、既にスレッドが待機しているサービスにサブミットします。たとえば、一度に1つのタスクのみをダウンロードしたい場合は、からExecutors.newScheduledThreadPool(1)に変更します。

編集:前回の回答はそのまま残しておきます。前のタスクが完了しました。 2つのExecutorServicesを使用します。 1人は評決されたエグゼクティブに提出し、もう1人はタイムリーな処刑を行います。最後に、最初のExecutorは完了を待機し、他のタスクがキューに入れられた状態で続行します。

ExecutorService e = Executors.newSingleThreadExecutor(); 
ScheduledExecutorService scheduledService = Executors.newScheduledThreadPool(1) 
public void submitTask(final Runnable r){ 
    e.submit(new Runnable(){ 
     public void run(){ 
      ScheduledFuture<?> future= scheduledService.schedule(r, defaultWaitTimeInMinutes, TimeUnit.MINUTES); 
      future.get(); 

     } 
    }); 
} 

ここでfuture.get(); submitTaskによって送信された次のRunnableが完了し、1分間実行されます。最後に、これは、他のタスクがサブミットされていなくても、タスクが1分待つ必要がある場合にのみ機能します。

+0

このメソッドは、実行権をスケジュールするのですか?私のダウンロードにはランダムな時間がかかります... 1分前に最後のタスクが完了してから次のタスクを開始するまでに、私はこれをどのように使うことができるのでしょうか? – DnBase

+0

@ user1105107私のアップデートを見てください。これにより、前のタスクが完了してから1分後にタスクをサブミットできます。私はもともとあなたの要求を見逃した –

+0

まあ私は私が非常によく説明しなかったことに気づいたそれは私のせいです、申し訳ありません。とにかく、あなたとあなたの解決策を試してみるすべての人に感謝します。 – DnBase

0

Java Concurrency packageには、尋ねることを行うためのクラスが含まれています。あなたが話している一般的な構成は、Executorで、これはThreadPoolによってサポートされています。実行可能ファイルのリストを生成し、Executorに送信します。エグゼキュータにはThreadPoolがあり、スレッドが利用可能になるとRunnablesを実行します。

ここでは例として、あなたはRunnableのような可能性がありそう:そして、あなたはダウンローダオブジェクトを作成し、ExecutorServiceのにそれを提出することにより、それを使用することができ

private static class Downloader implements Runnable { 

    private String file; 

    public Downloader(String file) { 
     this.file = file; 
    } 

    @Override 
    public void run() { 
     // Use HttpClient to download file. 
    } 
    } 

を:

public static void main(String[] args) throws Exception { 
    ExecutorService executorService = Executors.newFixedThreadPool(5); 
    for (String file : args) { 
     executorService.submit(new Downloader(file)); 
    } 
    executorService.awaitTermination(100, TimeUnit.SECONDS); 
    } 
関連する問題