使用Java,这种类型的设置和来自方法的调用是线程安全的吗?

使用Java,这种类型的设置和来自方法的调用是线程安全的吗?,java,multithreading,spring,thread-safety,Java,Multithreading,Spring,Thread Safety,我有一个服务类,它是一个接口的实现,并用Spring作为服务和单例进行注释。我有两个不同的方法,每个方法都创建一个字符串生成器局部变量。我有一个私有方法,它接受一个字符串生成器和一个字符串,这两个参数都是最终变量。此私有方法根据附加字符串变量中的信息向该字符串生成器追加信息。在每个实现的方法中,我调用传递本地创建的字符串生成器和必要字符串的私有方法 我确信这两个实现的方法是线程安全的,但我不确定私有方法。当我像那样通过字符串生成器时,它是线程安全的吗?是否将参数作为最终帮助?我假设final使线

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

我确信这两个实现的方法是线程安全的,但我不确定私有方法。当我像那样通过字符串生成器时,它是线程安全的吗?是否将参数作为最终帮助?我假设final使线程安全,但同时我认为拥有final意味着我不能向它添加任何内容

这个stackoverflow问题和答案表示不会,但在示例中,参数不是final,但可能这并不重要

以下是我所拥有的一个例子:

@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);
        } 
    }
}
@服务
@范围(“单例”)
公共类单音服务{
@凌驾
公共字符串buildSelect(最终整数id){
StringBuilder sb=新的StringBuilder(“从表中选择*);
映射属性=新的HashMap();
地址(sb、属性、id);
使某人返回字符串();
}
@凌驾
公共字符串构建计数(最终整数id){
StringBuilder sb=新StringBuilder(“从表中选择计数(id));
映射属性=新的HashMap();
地址(sb、属性、id);
使某人返回字符串();
}
私有void addWhere(最终StringBuilder sb、最终映射属性、最终整数id){
如果(id!=null){
sb.append(“其中id=:id);
属性。put(“id”,id);
} 
}
}

final
在方法签名中使用时绝对无效,只是为了避免意外地将某些内容分配给方法内的变量

除此之外…为什么这段代码不是线程安全的

您传递给公共方法的唯一内容是一个不可变的
整数
,并且方法外部的任何内容都不会被修改

是的,因为不涉及并发,所以这是线程安全的


也就是说,它也没有什么意义。您正在创建一个
映射,在其中放入一些东西,然后丢弃它。

是的,这是线程安全的


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

是的,看起来确实有点可笑。这不是整个类,只是一个简单的示例,我没有完全删除映射部分。我更担心字符串的生成。谢谢你的回答。关于变量的最后一个-我是changing变量的值,但间接通过它的append方法-如果我尝试为它分配一个新的字符串生成器实例,final将起作用?@Elrond-正确。
final
在java中意味着您不能在初始赋值后重新分配给变量;它与变量所持有的对象没有任何关系引用。您没有更改变量的值,而是使用变量引用的对象。请参阅: