在我的应用程序中,我有两个线程.每个线程与不同的外部实体通信.
让我们说T1 - > N1和T2 - > N2(T1和T2是两个线程.N1和N2是外部实体.通信是基于HTTPS的SOAP.)
N1的供应商要求使用密钥存储文件UPCC_client.store进行身份验证,同样我们使用了以下代码,
System.setProperty("javax.net.ssl.keyStore", "<file path>");
System.setProperty("javax.net.ssl.keyStorePassword", "<password>");
System.setProperty("javax.net.ssl.trustStore","<file path>");
System.setProperty("javax.net.ssl.trustStorePassword", "<password>");
Run Code Online (Sandbox Code Playgroud)
已使用T1线程中设置的上述属性重新启动应用程序,没有任何问题.T2开始遇到麻烦,因为T1设置的属性被T2使用.这背后的主要原因System.setProperty是JVM范围.如何解决这个问题?
Pet*_*rey 16
我怀疑你有一个设计问题,但有这个要求.
解决这个问题的唯一方法是我能想到的是使你的属性成为ThreadLocal.
public class ThreadLocalProperties extends Properties {
private final ThreadLocal<Properties> localProperties = new ThreadLocal<Properties>() {
@Override
protected Properties initialValue() {
return new Properties();
}
};
public ThreadLocalProperties(Properties properties) {
super(properties);
}
@Override
public String getProperty(String key) {
String localValue = localProperties.get().getProperty(key);
return localValue == null ? super.getProperty(key) : localValue;
}
@Override
public Object setProperty(String key, String value) {
return localProperties.get().setProperty(key, value);
}
}
// Make the properties thread local from here. This to be done globally once.
System.setProperties(new ThreadLocalProperties(System.getProperties()));
// in each thread.
System.setProperty("javax.net.ssl.keyStore", "my-key-store");
Run Code Online (Sandbox Code Playgroud)
除非有任何混淆,否则System.setProperties()不仅会设置属性,而是替换集合及其实现.
// From java.lang.System
* The argument becomes the current set of system properties for use
* by the {@link #getProperty(String)} method.
public static void setProperties(Properties props) {
SecurityManager sm = getSecurityManager();
if (sm != null) {
sm.checkPropertiesAccess();
}
if (props == null) {
props = new Properties();
initProperties(props);
}
System.props = props;
}
Run Code Online (Sandbox Code Playgroud)
通过使用此方法,系统属性的行为更改为调用setProperty()和getProperty()的线程本地
小智 5
我来到这里寻找一个解决方案来设置每个线程的系统属性。我在上面使用了 @Peter Lawrey 的优秀示例,这正是我所需要的,但有一个例外 - 我的代码需要在 servlet 容器(Tomcat)内运行,因此我有义务成为一名好公民,而不是改变预期的行为对于在同一 JVM 实例中运行的任何其他 Web 应用程序,可以使用 setProperty() 方法。为了解决这个问题,我将 Peter 的setProperty()方法重命名为setLocalProperty():
public Object setThreadLocalProperty(String key, String value) {
return localProperties.get().setProperty(key, value);
}
Run Code Online (Sandbox Code Playgroud)
通过这一更改,结果是对 setProperty() 的调用将全局更改该属性 - 这将是 JVM 中其他线程所需的行为。要仅更改本地线程的属性,请改为调用setThreadLocalProperty().
总之,如果您可以完全控制您的应用程序实例,那么 Peter 的代码应该非常适合您。然而,如果您的应用程序位于共享 JVM 中,或者您需要将系统属性“分层”到全局和线程本地,则上述一项修改应该适合您。
| 归档时间: |
|
| 查看次数: |
6122 次 |
| 最近记录: |