No, if the Javadoc makes no mention of thread-saftey then thread safety is not guaranteed ("synchronization is an implementation detail").[1] Add a synchronized
modifier to your generatePublicKey
method (or some other form of locking) to make it thread-safe and be sure to add a Javadoc comment noting that it is supposed to be thread-safe.
See also:
But maybe….
It looks like your use might be (that is, as hunter pointed out in the comments, once you have a KeyFactory
instance, it might be safe to call KeyFactory#generatePublic
from multiple threads).
A bit of source diving, KeyFactory.getInstance(String)
looks something like so:[2] [3]
public static KeyFactory getInstance(String algorithm)
throws NoSuchAlgorithmException {
return new KeyFactory(algorithm);
}
Which in turns calls:
private KeyFactory(String algorithm) throws NoSuchAlgorithmException {
this.algorithm = algorithm;
List<Service> list = GetInstance.getServices("KeyFactory", algorithm);
serviceIterator = list.iterator();
// fetch and instantiate initial spi
if (nextSpi(null) == null) {
throw new NoSuchAlgorithmException
(algorithm + " KeyFactory not available");
}
}
And nextSpi
looks like:
private KeyFactorySpi nextSpi(KeyFactorySpi oldSpi) {
synchronized (lock) {
// Truncated for brevity
}
}
And KeyFactory#generatePublic
looks something like so:
public final PublicKey generatePublic(KeySpec keySpec)
throws InvalidKeySpecException {
if (serviceIterator == null) {
return spi.engineGeneratePublic(keySpec);
}
// Truncated for brevity
}
It does look like the class does some locking in parts and not others, which (I imagine was for a purpose and) means that they took thread-saftey into consideration. It could mean that they had intended for it to be safe to construct and use a factory for the same algorithm on multiple threads but it might also not mean that. You would need to exhaustively check the code paths for race conditions.
That said, please don't build anything assuming a contract other than what's in the Javadoc.