0

私は、毎分スケジューラによって呼び出され、ftpからファイルを取得し、そのレコードをDBに保存するメソッドを持っています。私はこれは本当に処理するスレッド安全な方法になるだろう スケジュールされたメソッドをスレッドセーフにする

public synchronized void processData(String data){ 
    //do processing 
} 
..方法は、一度に複数のファイルを実行する必要がある場合、それはスレッドセーフな方法で動作するように、このスレッドを安全にする必要があります大量の負荷を正常に処理できますか?

+0

私のシナリオでは、schedulerが11時に呼び出され、1000個のファイルがprocessDataメソッドで処理されると想定できます。スケジューラーは1分ごとに起動するように構成されており、11:01に再度呼び出されますが、最初の1000個のファイルの処理は完了しません。このシナリオに対処する最善の方法は何でしょうか? 1.メソッド で同期キーワードを削除します。2.ファイルプロセスごとに新しいスレッドを開始します ? – Sanath

答えて

3

囲むオブジェクトのステートフルフィールドを使用しない限り、スレッドセーフです。

つまり、何が起こっているのかを把握する目的で、processData(String data)で操作またはアクセスされるクラスレベルのフィールドがある場合、スレッドセーフではありません。

例は、private Boolean hasConnection;と呼ばれるクラスレベルのフィールドです。このフィールドに接続が存在するかどうかを確認する必要がある場合は、スレッドセーフな方法はありません。

この要件を満たす場合は、​​キーワードをメソッドに追加する必要はありません。デフォルトではスレッドセーフであり、無制限の数のスレッドが同時にアクセスできます。

この要件を満たしていない場合は、スレッドセーフであるかどうかを判断するためにクラス全体を投稿する必要があります。

+1

ロックのObjectインスタンスを使用してメソッドレベルで同期されていませんか?つまり、すべてのインスタンスレベルのフィールドは保護されています... – rfeak

+0

@rfeakそれらは必ずしも完全に保護されているわけではありません。彼らが「公的」であれば、間違いなく保護されています。それらが '非公開'であるが '非同期'メソッドによってアクセスされる場合、それらはまた保護されない。 –

+0

私はそれを置く間違った方法が保護されていると思います。このメソッドで同期させると、ロック用のオブジェクトが使用されます。つまり、THATメソッド(またはそのクラスで同期マークが付けられた他のメソッド)に対して、オブジェクトインスタンスの変数に複数のスレッドが同時にアクセスできないことを意味します。私のポイントは、他のメソッドを同期して状態を変更する可能性があることをマークしている限り、そのメソッドの内部からインスタンス変数を使用できるということです。 – rfeak

2

不思議な "ファイルを処理する"操作が自己完結していると仮定すると、あなたが心配するべき最も重要なことは、DB接続です。共有しないで、接続文字列から毎回新しいものを取得し、 a connection pool。クラス内で共有状態にアクセスする必要がない場合は、メソッドを同期させないでください。さもなければ、あなたのメソッドは複数のスレッドで同時に進行することができません。

1

あなたの方法がどのようなリソースを使用するのか、どのリソースが共有されているのかを教えてください。

共通オブジェクトを使用しない場合は問題ありません。

共通リソースを使用する場合は、これらのリソースがスレッドセーフな方法でアクセスできること、または複数のスレッドからアクセスされないことを確認する必要があります。

あなたの質問はパフォーマンスです。一般的には、processDataは、データベースの使用中に完了するまでに時間がかかる方法のようです。ロックを取得するために必要な時間は、DBクエリに比べて最小です。だから、​​キーワードを使用しても、パフォーマンスに大きな影響はありません。

関連する問題