2016-08-23 14 views
1

現在Java/JavaFXの並行性を試しています。印刷は別のスレッドで実行する必要があります。そうしないと、JavaFXメインスレッドが数秒間フリーズします。今私の印刷は、この簡単な例で行われます。独立した単一のスレッドでジョブをキューする

public void print(PrintContent pt) { 
    setPrintContent(pt); 

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

@Override 
public void run() { 
    // send content to printer 
} 

このコードでは、プリンタと並行して多くの印刷ジョブを送信しています。したがって、私のプリンタは一度に1つの印刷ジョブしか処理できないというエラーが表示されます。 Threadsを再利用することはできないことを知っているので、スレッドをキューに入れる可能性があるかどうかを知りたいので、プリンタは一度に1つの印刷ジョブしか処理しません。

ご協力いただきありがとうございます。

+1

注意。 'setPrintContent(pt)'を呼び出すことによって、 'print(...) 'を呼び出すたびに' printContent'を別の値に設定します。あなたが作成したスレッドは、将来、ある(未確定の)ポイントでその値にアクセスしようとします。バックグラウンドスレッドに正しい印刷内容が表示されるという保証はありません。 –

+0

あなたは絶対に正しいです。非常に短時間で連続して2つ以上の印刷ジョブを送信すると、特に例外が発生します。 – Chiggiddi

+0

例外が発生しないので、間違ったものが印刷されるだけです。例外はあなたがすでに特定した問題のものです。 –

答えて

1

~~> WAY 1

あなたがあなた自身のBlockingQueueread this is very usefulを実装またはJavaからのデフォルトの実装を使用することができますライブラリtutorial

は、したがって、上記のリンクを読んだ後、あなたは

ようなあなたのクラスにメソッドを追加します3210

第二に、あなたがキューが空の場合、それはあなたが法に

queue.take(); 

を呼び出し、このスレッドは、新しいオブジェクトが追加されるまで、あなたので、待ってブロックされているloop.Insideながら無限に実行されているスレッドを実装CPU使用時間を心配する必要はありません。

最後に上限を設定することができます。たとえば、キュ​​ーには27個の項目が含まれます。

スレッド障害の場合、手動で再作成する必要があることに注意してください。

~~> WAY 2より良いアプローチ

あなたはエグゼキューインターフェイスを使用することができます。

ExecutorService executorService1 = Executors.newSingleThreadExecutor(); 

ドキュメントから:

は、単一の労働者を使用するエグゼキュータを作成します。スレッドは無制限のキュー で動作します。ただし、シャットダウン前に実行中に障害が発生したためにこの単一スレッドが終了すると、 が終了すると、新しいスレッドが実行され、後続のタスクを実行する必要がある場合は になります)。 タスクは、任意の時点で有効になります です。

以下の方法では、ジョブが正常に完了した場合に結果を取得します。

Future future = executorService.submit(new Callable(){ public Object call() throws Exception { System.out.println("Asynchronous Callable"); return "Callable Result"; } }); 

System.out.println("future.get() = " + future.get()); 

future.get()がnullを返した場合、ジョブは正常に終了しました。

executorService.shutdown();このExecutorService内のアクティブなスレッドがJVMのシャットダウンを妨げる可能性があるため、 executorService.shutdown();と覚えておいてください。あなたのコードでも同じ状態にアクセスしようとする複数のスレッドに苦しむ離れて、プリンタに複数の印刷ジョブを送るの問題から、

全チュートリアルhere

+0

こんにちはGoXr3Plus、あなたのヒントありがとうございます。 Executerについて読んでいるうちに、私はBlockingQueueにも出くわしました。エグゼクターがより良いアプローチであると思われる理由、またはこれら2つの主な違いは何ですか? – Chiggiddi

+0

btw、あなたのリンクは素晴らしいと読みやすいです! – Chiggiddi

+0

@Chiggidi Executorの実装は内部的に何らかのBlockingQueueを使用しています。私はあなた自身の実装方法を望んでいました.2つ目の方法を使用した後は、独自のコードを実装するのではなく、いくつかのコード行です。リンク上に – GOXR3PLUS

4

single threaded executorを使用して印刷ジョブを実行します。それは1つだけのバックグラウンドスレッドを作成して、ジョブをキューに入れます:

// it might be better not to make this static; but you need to ensure there is 
// only one instance of this executor: 
private static final Executor PRINT_QUEUE = Executors.newSingleThreadExecutor(); 

// ... 

public void print(PrintContent pt) { 

    PRINT_QUEUE.execute(() -> { 
     // send content to printer 
    }); 
} 
関連する問題