スケジューラーによって毎分呼び出されてftpからファイルを取得し、そのレコードを処理してDBに保持するメソッドがあります。メソッドが一度に複数のファイルを実行する必要がある場合に、スレッドセーフな方法で動作するように、このスレッドをセーフにする必要があります。
public synchronized void processData(String data){
//do processing
}
これは本当に大量の負荷を適切に処理するスレッドセーフな方法になるのでしょうか?
スケジューラーによって毎分呼び出されてftpからファイルを取得し、そのレコードを処理してDBに保持するメソッドがあります。メソッドが一度に複数のファイルを実行する必要がある場合に、スレッドセーフな方法で動作するように、このスレッドをセーフにする必要があります。
public synchronized void processData(String data){
//do processing
}
これは本当に大量の負荷を適切に処理するスレッドセーフな方法になるのでしょうか?
囲んでいるオブジェクトのステートフルフィールドを使用しない限り、スレッドセーフです。
言い換えると、processData(String data)
何が起こっているかを追跡する目的で操作またはアクセスされるクラスレベルのフィールドがある場合、それはスレッドセーフではありません。
例としては、次のようなクラスレベルのフィールドprivate Boolean hasConnection;
があります。このフィールドとの接続が存在するかどうかを確認する必要がある場合、スレッドセーフなメソッドはありません。
この要件を満たしている場合はsynchronized
、メソッドにキーワードを追加する必要もありません。デフォルトではスレッドセーフであり、無制限の数のスレッドが同時にアクセスできます。
この要件を満たしていない場合は、クラス全体を投稿して、スレッドセーフかどうかを判断する必要があります。
不思議な「ファイルの処理」操作が自己完結型であると仮定すると、心配する必要がある最大のことはDB接続です。共有せず、接続文字列から毎回新しい接続を取得し、接続プールを使用します。クラス内の共有状態にアクセスする必要がない限り、メソッドを同期させないでください。そうしないと、メソッドは複数のスレッドで同時に進行できなくなります。
メソッドが使用するリソースと、それらのリソースのどれが共有されているかを説明してください。
共通オブジェクトを使用しなくても問題ありません。
共通のリソースを使用する場合は、これらのリソースにスレッドセーフな方法でアクセスできること、または複数のスレッドからアクセスできないことを確認する必要があります。
あなたの質問はパフォーマンスについてです。一般に、processData
完了するまでに時間がかかる方法のようです。データベースを使用しています。ロックを取得するために必要な時間は、DBクエリと比較して最小限です。したがって、このsynchronized
キーワードはパフォーマンスに目立った影響を与えることはありません。