Spring Service方法的线程安全性

3

我有一个Spring 3的服务方法,我希望从中返回PrivateKey / PublicKey密钥对 - 在服务中将KeyPairGenerator作为实例级变量是线程安全的吗?以避免在方法调用中调用KeyPairGenerator.getInstance(algo)并初始化它,还是应该将KeyPairGenerator保留在服务方法本地,并为每个方法调用调用.getInstance(algo)和.initialize(...),例如:

public KeyPair getKeyPair() throws ... {
    KeyPairGenerator keyGenerator = KeyPairGenerator.getInstance(algo);
    keyGenerator.initialize(1024);
    return (keyGenerator.genKeyPair());
}

或者

public KeyPair getKeyPair() throws ... {
    // use instance level keyGenerator that has been previously initialized
    return (keyGenerator.genKeyPair());
}

第二种方法是否存在可能的并发问题?第一种方法的性能惩罚是否显著?


顺便提一下,在你的返回语句中的括号是不必要的。 - matt b
1个回答

4
这个问题并不涉及到Spring。我相信你在谈论 Java 的 KeyPairGenerator。JavaDoc 上没有关于线程安全的说明,但在源代码中有注释
//  * although not specified, KeyPairGenerators could be thread safe,
//    so we make sure we do not interfere with that

“可能是线程安全的”对我来说毫无意义,特别是在查看访问keypairgenerator可能不是线程安全的问题之后:

密钥对生成器的并发属性是spi特定的,可能不是线程安全的。这可能会导致挂起前端的故障。

因此,我的建议是在每次调用时创建新实例,或者池化它们


感谢您的反馈和链接。我也在源代码中看到了那个评论-我猜这取决于加密提供者,而没有合同强制要求保证。我认为问题也与Spring有关,如果KeyGenerator可能不是线程安全的,我需要知道默认的@Service注释类的行为(我认为是单例?)是方法调用周围有锁定,还是它们可以并发运行,并且服务内部没有共享状态是安全的? - jc1001
2
@jc1001:不,没有同步,多个线程可以运行相同的bean方法。您可以像EJB一样池化Spring bean,但这有点hacky。 - Tomasz Nurkiewicz
谢谢Tomasz,我会对KeyPairGenerator初始化时间进行一些测试,看看是否需要在keyGenerator.genKeyPair()周围同步块,并且是否比将其局部化到服务方法中有任何好处。 - jc1001

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接