2

私は最近、データベースアクセスを含むいくつかのバックグラウンドプロセス(レポート生成など)を実行するためにQuartzスケジューラを使用しました。今、このバックグラウンドタスクは別々のスレッドで実行されます。ただし、データベースへのアクセスは、私のアプリケーションで中心点に行われ、実際のクエリを実行する前に、Javaデスクトップ - どのようにUIスレッドからデータベースアクセスを分離するのですか?

System.err.println("CURRENT THREAD: "+ Thread.currentThread().getName()); 

版画「メイン」、のようなもの。したがって、私は、データベースの読み取りは、UIスレッド( "メイン"スレッド)によって行われると思っています。これはUIが(部分的に)彼の応答性を失うという事実によっても確認される。可能であれば、可能な場合は、別のスレッドですべてのデータベースアクセスを実行し、その結果必要になる場合は、キャンセルボタンをクエリ要求に実装できるようにします。だから、私はこの労働者を持っていると想像します:

  • UIスレッド:
  • データベースアクセススレッド:dbからデータを取得します。
  • スケジュールされたバックグラウンドタスク:それ以外はすべて(およびDBアクセススレッドを使用します)。

    これは実現できますか?あるいは、私のアプローチに代わるより良い選択肢がありますか?

P.S.私はこの時点で、この問題(Hibernate、Springなど)に対処するいくつかの既存のフレームワークを使用したくありません。私はちょうど自家製の、働く解決策を必要とします。

スタックトレース:

at com.mycompany.myproduct.core.db.SQL.executeQuery(SQL.java:260) 
at com.mycompany.myproduct.core.db.Database.getAbstractDBObjects(Database.java:285) 
at com.mycompany.myproduct.core.db.Database.getAbstractDBObjects(Database.java:305) 
at com.mycompany.myproduct.core.util.job.DummyJobProcessor$1.run(DummyJobProcessor.java:61) 
at org.eclipse.swt.widgets.RunnableLock.run(Unknown Source) 
at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Unknown Source) 
at org.eclipse.swt.widgets.Display.runAsyncMessages(Unknown Source) 
at org.eclipse.swt.widgets.Display.readAndDispatch(Unknown Source) 
at com.mycompany.myproduct.core.ui.layers.AbstractView.open(AbstractView.java:915) 
at com.mycompany.myproduct.mycompany.open(mycompany.java:196) 
at com.mycompany.myproduct.mycompany.main(mycompany.java:365) 
+0

質問を読んだ後、あなたのUIが影響を受けないように、別のスレッドからデータベースへのアクセスを実行しているようです。私は正しい? –

+0

@Sunny Guptaはい。 – hypercube

答えて

1

あなたのDBクエリがUIスレッドから実行されているようにあなたがスケジュールされたタスクは、クエリを実行することを言っていてもそうです(?)。あなたの提案された解決策にかけ

new Exception().printStacktrace(); 

:確かに、あなたは、データベースにアクセススタックトレースをプリントアウトすることができ、あなたのDBクエリが遅く、そうでない場合は、あなたのUIを凍結するかどうそれはまともなデザインのように思えます。 UIレイヤーとdbレイヤーの間にイベントシステムを実装できます。単純なキューベースのアプローチかもしれません。

EDIT:

イベントベースのソリューションを実装する方法を見つけるための最も可能性の高い例があります。

免責事項:私は何年もの間、実際のUIプログラミングを行っていません。

  1. ユーザーがUIのボタンをクリックします。 UIスレッドは、イベントオブジェクト(DataWantedEvent)をキュー(java.util.Queue)に配置し、ラベルを変更し( "Waiting for data ...")、その後、他のユーザーとのやりとりを待ちます。
  2. dbレイヤーのスレッドは、キューからイベントを受け取り、データベースに照会します。結果は結果オブジェクトの別のキューにポストバックされます。
  3. UIスレッド(主スレッドではない)が結果キューから結果オブジェクトを取得し、UIを更新します。

結果オブジェクトをUIにポストするためのキューが必要ない場合があります。更新メソッドを直接呼び出すことができます。

ユーザーがキャンセルボタンをクリックすると、更新イベント/コールバックが無視されるか、可能であればdbクエリがキャンセルされる可能性があります。

+0

質問の更新をご覧ください。 – hypercube

+0

このアイデアをイベントシステムで拡張していただけますか? – hypercube

0

UIを直接更新するリスナーの実装を持つことができます。関数コールバックのようなもので、UIスレッドにイベントを与えます。

このようにして、ビジネスロジックで同期DBリクエストが不要な場合、UIスレッドは入力リクエストの処理を継続できます。

いつでも非同期で実行できます。

HTH。

関連する問題