0

インターフェイスの実装であるサービス クラスがあり、Spring as a service および singleton で注釈が付けられています。それぞれが文字列ビルダーのローカル変数を作成する 2 つの異なる方法があります。文字列ビルダーと文字列を受け取るプライベート メソッドがあり、両方のパラメーターが最終変数です。このプライベート メソッドは、その追加の文字列変数で見つかった情報に応じて、その文字列ビルダーに情報を追加します。実装された各メソッドで、ローカルに作成された文字列ビルダーと必要な文字列を渡すプライベート メソッドを呼び出します。

実装された 2 つのメソッドはスレッド セーフであると確信していますが、プライベート メソッドについては確信が持てません。そのように渡すと、その文字列ビルダーはスレッドセーフですか? 最終的な助けとしてパラメータを持っていますか? final がそのスレッドセーフになったと思いましたが、同時に、final にすることは何も追加できないことを意味すると思いました。

このstackoverflowの質問と回答では、そうではないと言われていますが、例ではパラメーターは最終的ではありませんが、それは問題ではないかもしれません。

その StringBuilder 変数は、このコードでスレッドセーフですか?

これが私が持っているものの例です:

@Service
@Scope("singleton")
public class SingletonService {

    @Override
    public String buildSelect(final Integer id){
        StringBuilder sb = new StringBuilder("select * from table ");
        Map<String,Object> properties = new HashMap<String,Object>();
        addWhere(sb,properties,id);
        return sb.toString();
    }

    @Override
    public String buildCount(final Integer id){
        StringBuilder sb = new StringBuilder("select count(id) from table ");
        Map<String,Object> properties = new HashMap<String,Object>();
        addWhere(sb,properties,id);
        return sb.toString();
    }

    private void addWhere(final StringBuilder sb, final Map<String,Object> properties, final Integer id){
        if(id != null){
            sb.append("where id = :id);
            properties.put("id",id);
        } 
    }
}
4

2 に答える 2

1

finalメソッド シグネチャで使用しても、メソッド内の変数に誤って何かを代入することはできません。

それ以外は...なぜこのコードはスレッドセーフではないのでしょうか?

パブリック メソッドに渡す唯一のものIntegerは不変であり、メソッドの外部にあるものは変更されません。

そうです、並行性が関与しないため、これはスレッドセーフです。

とは言っても、あまり意味がありません。を作成し、そのMap中に何かを入れてから破棄しています。

于 2013-05-10T14:42:02.727 に答える