次のシグネチャを持つ静的メソッドがあります。
public static List<ResultObjects> processRequest(RequestObject req){
// process the request object and return the results.
}
上記のメソッドに対して同時に複数の呼び出しが行われるとどうなりますか?リクエストは同時に処理されますか、それとも次々に処理されますか?
次のシグネチャを持つ静的メソッドがあります。
public static List<ResultObjects> processRequest(RequestObject req){
// process the request object and return the results.
}
上記のメソッドに対して同時に複数の呼び出しが行われるとどうなりますか?リクエストは同時に処理されますか、それとも次々に処理されますか?
あなたの質問に正確に答える:
synchronized
同時アクセスが必要なオブジェクトを操作している場合は、修飾子を追加する必要があります。
メソッドへのすべての呼び出しは同時に実行されます...しかし:
静的メソッドのコードが静的変数を変更するとすぐに、同時実行の問題が発生する可能性があります (スレッドセーフでない状況になる)。この場合、メソッドを次のように宣言できます。synchronized
メソッドがローカル変数のみを使用する場合、同時実行の問題は発生しません。
同時実行を回避する必要がある場合は、明示的に同期する必要があります。メソッドが静的であるという事実は、それとは何の関係もありません。メソッド自体をであると宣言するとsynchronized
、同期はクラスオブジェクトで行われます。それ以外の場合は、静的オブジェクトで同期する必要があります(this
静的メソッドには存在しないため)。
自分で確認できます:
public class ConcurrentStatic {
public static void main(String[] args) {
for (String name: new String[] {"Foo", "Bar", "Baz"}) {
new Thread(getRunnable(name)).start();
}
}
public static Runnable getRunnable(final String name) {
return new Runnable() {
public void run() {
longTask(name);
}
};
}
public static void longTask(String label) {
System.out.println(label + ": start");
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(label + ": end");
}
}
デフォルトでは、Javaの個別のスレッドからのすべてのメソッド呼び出しは同時です。