0

我有一个服务类,它是一个接口的实现,并用 Spring 作为服务和单例进行了注释。我有两种不同的方法,每种方法都创建一个字符串生成器局部变量。我有一个私有方法,它接受一个字符串生成器和一个字符串,两个参数都是最终变量。此私有方法根​​据在该附加字符串变量中找到的信息将信息附加到该字符串构建器。在每个实现的方法中,我调用该私有方法,传递本地创建的字符串生成器和必要的字符串。

我相信这两个实现的方法是线程安全的,但我不确定私有方法。当我这样传递它时,那个字符串生成器线程安全吗?将参数作为最终帮助吗?我认为 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 回答
1

是的,这是线程安全的。

每个线程都有自己的堆栈存储变量。在这种情况下,变量是对由该线程创建的实例的引用,每个线程一个StringBuilder。will的实例StringBuilder已在堆中创建,因此可以共享,但您必须在线程之间显式传递引用才能发生这种情况。

于 2013-05-10T14:45:27.607 回答