2012-03-15 9 views
0

私はJavaのスレッディングについては新しいことを認めますが、私はjava.util.concurrentについて多くの読書をしています。私は本当の人が答えることを望んでいました。スレッドの質問 - java.util.concurrent - Runnable/Callable

まず、Runnable/Callableメソッドの実行に役立つThreadPoolExecutorとBlockQueueを作成しました。私の限られた既知のものを単純に保つために、私はすべてのアクティビティを読み取り専用に制限し、Runnableに渡されたオブジェクトは変更されず、作成された情報は、アプリケーションがGUIテーブルを作成するために使用するデータベースデータベースは受信前または受信後に変更できますが、表示目的には関係ありません。

私が興味深いのは、スレッドセーフであることです。 ThreadPoolExecutorを拡張したので、スレッドで作業が終了した後にRunnable内のメソッドを実行するためにafterExecuteメソッドをオーバーライドできます。私が読んだところでは、この操作はメインスレッドで行われ、スレッドセーフであると考えられます。

また、この考え方を続けると、このRunnable/Callableクラス内にある別のメソッドを記述し、run(またはThreadPoolExecutor.execute())を使わずに直接使用すると、メインスレッドでも実行されますそして安全です。質問2:Runnableクラスのrun()メソッドからこのメソッドを使用すると、スレッド上で実行されますか? (私はそれを仮定し、確認を求める)と私は直接このメソッドを実行する場合は、メインスレッド上で実行されるだろうか?

理由は、1つのクラス内でクエリ/更新/挿入と関係がありますが、メインスレッドのデータベースを更新する必要があるためです。

説明するためのコードのビット:

拡張ThreadPoolExecutor:

public class DatabaseThreadPoolExecutor extends ThreadPoolExecutor { 
    public DatabaseThreadPool(int corePoolSize, int maximumPoolSize, long keepAlive, TimeUnit unit, BlockingQueue<Runnable> workQueue) { 
     super(//pass info to super) 
    } 

    protected void afterExecute(Runnable runnable, Throwable throwable) { 
     if(runnable instanceof someRunnable) { 
      ((SomeRunnable) runnable).afterExecution(); 
     } 
    } 
} 

のRunnableクラス:doSomethingのを呼び出し

public class someRunable implements Runable { 

    public someRunnable() { 
     // used code withing thread 
    } 

    public doAfterExecute() { 
     // run by ThreadPoolExecutor .afterExecute() 
    } 

    public doSomething() { 
     // Run by someRunnable in thread 
     // Also run directly by some other class 
    } 
} 

他のクラス():

public class someOtherClass { 
    public SomeOtherClass(Runnable someRunnable) { 
     someRunable.doSomething(); 
    } 
} 
+0

「メインスレッド」と言うときは、Swing/AWTイベントスレッドを参照していますか? –

+0

少しのコードで簡単に答えることができます。 – moodywoody

+0

タイトルのCallableはどこに入っていますか? – kylewm

答えて

1

すべてのコードを見ることなく、そのような高レベルの記述が「スレッドセーフ」であるとは言えません。私たちが知っていることは、「読み取り」がブロック操作であり、それがあなたのデッドロックになるというアーキテクチャを使用していることです。

一般に、リソースまたはクラスを「スレッドセーフ」と記述することは、複数のスレッドが使用すると予測できない動作を示さないことを意味します。しかし、特定のリソースが「スレッドセーフ」であるという証明は、あなたが並列でスレッドを実行しようとしたときにバグを引き起こさないという証明ではありません。ちょうどその行動は予測可能です(任意の与えられた一連のタイミングについてはもちろん、それ自体は予測できません)。

スレッドセーフであることは、何かが非常に並行使用に実際に適していることを示すものでもありません。完全に同期化されたArrayListは 'threadsafe'ですが、あなたは常にそれを使用するスレッドの多くの間で共有するプログラムを作成したくありません!

は、私は私の のRunnable /呼び出し可能なメソッドを実行するために役立つThreadPoolExecutorとBlockQueueを作成しました!:

まずかかわらず、あなたの実際の質問に答えることを試みます。私は読み取り専用にすべての活動を制限している私の限られた knownledgeで物事をシンプルに保つために、Runnableをへ を通過したいかなるオブジェクトは、これは明らかに虚偽の陳述のように思える

を変更されません。あなたの実行可能ファイルが何かをしているなら、あなたが読んでいるものはどこかに行くはずです。どこかには、実行可能ファイルに参照があるものでなければなりません。 あなたが読取り結果を同時アクセスに応答するようにするリソースは、を分析するために必要なものです。それが潜在的な危険がある場所です。

私はそれが終了した後 スレッドでその作業をRunnableを内メソッドを実行するためにafterExecute メソッドをオーバーライドすることができますので、私はThreadPoolExecutorを高めています。私が読んだところでは、この の操作はメインスレッドで行われ、スレッド と考えられます。

いいえ、実行後にExecute()メソッドを呼び出した同じプールスレッドでExecute()が呼び出されます。 Runnableを送信したスレッドではありません。 「This method is invoked by the thread that executed the task

はまた、この考えにcontinueing私はこのRunnableを/呼び出し可能なクラス内 もある別の方法を書いて、 せずに直接(またはThreadPoolExecutor.execute())がそれを実行するのに使用し、それを使用する場合また、 メインスレッドで実行し、安全です。

はいこれは、プールスレッドではなく、メソッドを呼び出すスレッドで実行されます。 "安全である"とは、単にアーキテクチャの説明(そして安全についての同意した定義)から始めることができないものです:)。

質問2: Runnableクラスのrun()メソッドからこのメソッドを使用すると、スレッド上で実行されますか? (私はそれがあると仮定し、そして 確認を求め)

はい、あなたはrun()メソッド内で呼び出して何があなたの仕事をピックアップし、プールのスレッドで実行されます。

+0

まあ、私のアイデアにはいくつかの修正が必要だと思うかもしれません。たぶんいくつかの良い読み方へのリンクが必要です。おそらく私がやろうとしていることのよりよい記述です。メインのアプリケーションを一時停止することなく、長いデータベース呼び出しから情報を取得する必要があります。サーバーをスリープ状態にすることはできません。情報をメインアプリケーションに戻す必要があります。私が見つけたすべての例は、Lockまたは同期オブジェクトを待ってメインコードを停止しています。 –

+0

私は最初に過度に悲観的だった場合は申し訳ありません。あなたは確かに物事に正しく近づいており、正しい方向に向かっています。私はおそらく、スレッドセーフという用語の非常に可変な定義について、あまりにも多くの個人的な心配を持っています。 (また、スレッドセーフなアーキテクチャを想定する傾向があることは、「単一スレッドバージョンにはなかった同時リソース使用によるバグはありません」ということを意味します)。 – Affe

+0

それはまったく問題ありません。私は本とインターネットで作業しているので、私のアイデアは修正する必要があります;)あなたは非常に正しいので、私の質問に答えましたが、残念ながらもっと多くのことが開かれました。 –