SSLContext.createSSLEngine()是否线程安全?
我使用Java 6中的默认JSSE提供程序(SunJSSE),如下所示SSLContext.createSSLEngine()是否线程安全?,ssl,java-6,jsse,Ssl,Java 6,Jsse,我使用Java 6中的默认JSSE提供程序(SunJSSE),如下所示 SSLContext sslCtx=SSLContext.getInstance(“TLS”) 我可以从多个线程安全地调用方法sslCtx.createSSLEngine() 更新1: 以这种方式调用createsLengine()的代码仅在服务器端运行。基本上,线程对连接到服务器的每个客户端都调用此方法。对SSLContext.createSSLEngine()的调用似乎是线程安全的。至少基于应用程序没有因任何与竞争条件相
SSLContext sslCtx=SSLContext.getInstance(“TLS”)代码>
我可以从多个线程安全地调用方法sslCtx.createSSLEngine()
更新1:
以这种方式调用createsLengine()
的代码仅在服务器端运行。基本上,线程对连接到服务器的每个客户端都调用此方法。对SSLContext.createSSLEngine()
的调用似乎是线程安全的。至少基于应用程序没有因任何与竞争条件相关的错误而失败这一事实
为了找到一个明确的答案,我下载了的源代码并查看了一下。当然,我假设这与Oracle的JRE 6中的代码相同
调用SSLContext.createSSLEngine()
时,它会依次调用抽象方法engineCreateSSLEngine()
,该方法对javax.net.ssl.SSLContextSpi
类的任何实现进行调用。在本例中,实现是sun.security.ssl.SSLContextImpl
。SSLContextImpl
提供的engineCreateSSLEngine()
方法的实现只需通过调用sslenginimpl(SSLContextImpl ctx)
构造函数返回的新实例
检查代码时,我没有发现任何可能的线程不安全操作。我也同意Elliot关于OpenJDK8中SSLContext.createSSLEngine()
的线程安全性(基于分析代码和执行简单测试)
我添加了这个答案,因为在某些情况下,您必须重新使用SSLContext
s(如果您不喜欢包装类或无法使用同步):当使用SSL加密连接到Wildfly应用程序服务器EJB时,jboss远程处理EndpointImpl
决定基于包含SSLContext
实例的ConnectionKey
打开一个新连接。因此,如果您总是为每个EJB调用指定一个新的SSLContext
,那么总是使用一个新连接。可悲的是,连接被认为是“共享的”,因此在调用后它不会关闭(但由于不同的ConnectionKey
s,因此永远不会重复使用)。一段时间后,您将只能获得其中许多:
Caused by: java.net.SocketException: No buffer space available
at sun.nio.ch.Net.socket0(Native Method) ~[?:1.8.0_91]
at sun.nio.ch.Net.socket(Net.java:411) ~[?:1.8.0_91]
at sun.nio.ch.Net.socket(Net.java:404) ~[?:1.8.0_91]
at sun.nio.ch.SocketChannelImpl.<init>(SocketChannelImpl.java:105) ~[?:1.8.0_91]
at sun.nio.ch.SelectorProviderImpl.openSocketChannel(SelectorProviderImpl.java:60) ~[?:1.8.0_91]
at java.nio.channels.SocketChannel.open(SocketChannel.java:145) ~[?:1.8.0_91]
at org.xnio.nio.WorkerThread.openTcpStreamConnection(WorkerThread.java:250) ~[xnio-nio-3.6.2.Final.jar:3.6.2.Final]
at org.xnio.XnioIoThread.internalOpenTcpStreamConnection(XnioIoThread.java:247) ~[xnio-api-3.6.2.Final.jar:3.6.2.Final]
at org.xnio.XnioIoThread.openStreamConnection(XnioIoThread.java:226) ~[xnio-api-3.6.2.Final.jar:3.6.2.Final]
at org.xnio.XnioWorker.openStreamConnection(XnioWorker.java:398) ~[xnio-api-3.6.2.Final.jar:3.6.2.Final]
at org.jboss.remoting3.remote.RemoteConnectionProvider.createSslConnection(RemoteConnectionProvider.java:246) ~[jboss-remoting-5.0.0.
at org.jboss.remoting3.remote.HttpUpgradeConnectionProvider.createSslConnection(HttpUpgradeConnectionProvider.java:136) ~[jboss-remot
at org.jboss.remoting3.remote.RemoteConnectionProvider.connect(RemoteConnectionProvider.java:206) ~[jboss-remoting-5.0.0.Final.jar:5.
at org.jboss.remoting3.EndpointImpl.lambda$connect$6(EndpointImpl.java:618) ~[jboss-remoting-5.0.0.Final.jar:5.0.0.Final]
at java.security.AccessController.doPrivileged(Native Method) ~[?:1.8.0_91]
at org.jboss.remoting3.EndpointImpl.connect(EndpointImpl.java:617) ~[jboss-remoting-5.0.0.Final.jar:5.0.0.Final]
at org.jboss.remoting3.EndpointImpl.connect(EndpointImpl.java:536) ~[jboss-remoting-5.0.0.Final.jar:5.0.0.Final]
at org.jboss.remoting3.ConnectionInfo$None.getConnection(ConnectionInfo.java:83) ~[jboss-remoting-5.0.0.Final.jar:5.0.0.Final]
at org.jboss.remoting3.ConnectionInfo.getConnection(ConnectionInfo.java:56) ~[jboss-remoting-5.0.0.Final.jar:5.0.0.Final]
at org.jboss.remoting3.EndpointImpl.doGetConnection(EndpointImpl.java:487) ~[jboss-remoting-5.0.0.Final.jar:5.0.0.Final]
at org.jboss.remoting3.EndpointImpl.getConnectedIdentity(EndpointImpl.java:433) ~[jboss-remoting-5.0.0.Final.jar:5.0.0.Final]
at org.jboss.remoting3.UncloseableEndpoint.getConnectedIdentity(UncloseableEndpoint.java:51) ~[jboss-remoting-5.0.0.Final.jar:5.0.0.F
at org.jboss.remoting3.Endpoint.getConnectedIdentity(Endpoint.java:122) ~[jboss-remoting-5.0.0.Final.jar:5.0.0.Final]
at org.jboss.ejb.protocol.remote.RemoteEJBReceiver.lambda$getConnection$2(RemoteEJBReceiver.java:185) ~[jboss-ejb-client-4.0.9.Final.
at java.security.AccessController.doPrivileged(Native Method) ~[?:1.8.0_91]
at org.jboss.ejb.protocol.remote.RemoteEJBReceiver.getConnection(RemoteEJBReceiver.java:185) ~[jboss-ejb-client-4.0.9.Final.jar:4.0.9
at org.jboss.ejb.protocol.remote.RemoteEJBReceiver.processInvocation(RemoteEJBReceiver.java:128) ~[jboss-ejb-client-4.0.9.Final.jar:4
at org.jboss.ejb.client.EJBClientInvocationContext.sendRequest(EJBClientInvocationContext.java:454) ~[jboss-ejb-client-4.0.9.Final.ja
原因:java.net.SocketException:没有可用的缓冲区空间
在sun.nio.ch.Net.socket0(本机方法)~[?:1.8.0_91]
在sun.nio.ch.Net.socket(Net.java:411)~[?:1.8.091]
在sun.nio.ch.Net.socket(Net.java:404)~[?:1.8.091]
在sun.nio.ch.socketchannelmpl.(socketchannelmpl.java:105)~[?:1.8.091]
在sun.nio.ch.SelectorProviderImpl.openSocketChannel(SelectorProviderImpl.java:60)~[?:1.8.091]
在java.nio.channels.SocketChannel.open(SocketChannel.java:145)~[?:1.8.091]
在org.xnio.nio.WorkerThread.openTcpStreamConnection(WorkerThread.java:250)~[xnio-nio-3.6.2.Final.jar:3.6.2.Final]
在org.xnio.xniiothread.internalOpenTcpStreamConnection(xniiothread.java:247)~[xnio-api-3.6.2.Final.jar:3.6.2.Final]
在org.xnio.xniiothread.openStreamConnection(xniiothread.java:226)~[xnio-api-3.6.2.Final.jar:3.6.2.Final]
在org.xnio.xniower.openStreamConnection(xniower.java:398)~[xnio-api-3.6.2.Final.jar:3.6.2.Final]
在org.jboss.remoting3.remote.RemoteConnectionProvider.CreateSLConnection(RemoteConnectionProvider.java:246)~[jboss-remoting-5.0.0。
在org.jboss.remoting3.remote.HttpUpgradeConnectionProvider.createSslConnection(HttpUpgradeConnectionProvider.java:136)~[jboss-remot
在org.jboss.remoting3.remote.RemoteConnectionProvider.connect(RemoteConnectionProvider.java:206)~[jboss-remoting-5.0.0.Final.jar:5。
在org.jboss.remoting3.EndpointImpl.lambda$connect$6(EndpointImpl.java:618)~[jboss-remoting-5.0.0.Final.jar:5.0.0.Final]
在java.security.AccessController.doPrivileged(本机方法)~[?:1.8.091]
在org.jboss.remoting3.EndpointImpl.connect(EndpointImpl.java:617)~[jboss-remoting-5.0.0.Final.jar:5.0.0.Final]
在org.jboss.remoting3.EndpointImpl.connect(EndpointImpl.java:536)~[jboss-remoting-5.0.0.Final.jar:5.0.0.Final]
在org.jboss.remoting3.ConnectionInfo$None.getConnection(ConnectionInfo.java:83)~[jboss-remoting-5.0.0.Final.jar:5.0.0.Final]
在org.jboss.remoting3.ConnectionInfo.getConnection(ConnectionInfo.java:56)~[jboss-remoting-5.0.0.Final.jar:5.0.0.Final]
在org.jboss.remoting3.EndpointImpl.doGetConnection(EndpointImpl.java:487)~[jboss-remoting-5.0.0.Final.jar:5.0.0.Final]
在org.jboss.remoting3.EndpointImpl.getConnectedIdentity(EndpointImpl.java:433)~[jboss-remoting-5.0.0.Final.jar:5.0.0.Final]
在org.jboss.remoting3.UncloseableEndpoint.getConnectedIdentity(UncloseableEndpoint.java:51)~[jboss-remoting-5.0.0.Final.jar:5.0.0.F
在org.jboss.remoting3.Endpoint.getConnectedIdentity(Endpoint.java:122)~[jboss-remoting-5.0.0.Final.jar:5.0.0.Final]
在org.jboss.ejb.protocol.remote.RemoteEJBReceiver.lambda$getConnection$2(RemoteEJBReceiver.java:185)~[jboss-ejb-client-4.0.9.Final。
在java.security.AccessController.doPrivileged(本机方法)~[?:1.8.091]
在org.jboss.ejb.protocol.remote.RemoteEJBReceiver.getConnection(RemoteEJBReceiver.java:185)~[jboss-ejb-client-4.0.9.Final.jar:4.0.9
在org.jboss.ejb.protocol.remote.RemoteEJBReceiver.processInvocation(RemoteEJBReceiver.java:128)~[jboss-ejb-client-4.0.9.Final.jar:4
在org.jboss.ejb.client.EJBClientInvocationContext.sendRequest(EJBClientInvocationContext.java:454)~[jboss-ejb-client-4.0.9.Final.ja
重新使用静态的SSLContext
修复了这个问题。它没有这样说,但我没有