# 池

> 原文： [https://docs.oracle.com/javase/tutorial/jndi/ldap/pool.html](https://docs.oracle.com/javase/tutorial/jndi/ldap/pool.html)

创建连接时描述[连接创建](create.html)部分。它描述了几个 `Context` 实例如何共享同一个连接。

LDAP 服务提供商支持的另一种连接共享称为 _ 连接池 _。在这种类型的共享中，LDAP 服务提供者维护一个（可能）先前使用的连接池，并根据需要将它们分配给 `Context` 实例。当 `Context` 实例完成连接（关闭或垃圾收集）时，连接将返回到池中以供将来使用。请注意，这种共享形式是顺序的：从池中检索连接，使用，返回到池，然后再从池中检索另一个 `Context` 实例。

每个 Java 运行时系统都维护连接池。在某些情况下，连接池可以显着提高性能。例如，如果使用连接池，则只需要一个连接来处理包含对同一 LDAP 服务器的四个引用引用的搜索响应。如果没有连接池，这种情况将需要四个单独的连接。

本课程的其余部分将更详细地介绍如何使用连接池。

## 如何使用连接池

您通过将属性`“com.sun.jndi.ldap.connect.pool”`添加到传递给初始上下文构造函数的环境属性来请求连接池。这是 [`an example`](examples/UsePool.java) 。

```
// Set up environment for creating initial context
Hashtable env = new Hashtable(11);
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, "ldap://localhost:389/o=JNDITutorial");

// Enable connection pooling
env.put("com.sun.jndi.ldap.connect.pool", "true");

// Create one initial context (Get connection from pool)
DirContext ctx = new InitialDirContext(env);

// do something useful with ctx

// Close the context when we're done
ctx.close();   // Return connection to pool

// Create another initial context (Get connection from pool)
DirContext ctx2 = new InitialDirContext(env);

// do something useful with ctx2

// Close the context when we're done
ctx2.close();   // Return connection to pool

```

此示例连续创建两个初始上下文。第二个初始上下文将重用第一个使用的连接。要运行此程序并观察如何检索连接并将其返回到池，请使用以下命令行。

```
#java -Dcom.sun.jndi.ldap.connect.pool.debug=fine UsePool

```

这应该产生如下所示的输出。

```
Create com.sun.jndi.ldap.LdapClient@5d173[localhost:389]
Use com.sun.jndi.ldap.LdapClient@5d173
{ou=ou: NewHires, objectclass=objectClass: top, organizationalUnit}
Release com.sun.jndi.ldap.LdapClient@5d173
Use com.sun.jndi.ldap.LdapClient@5d173
{ou=ou: People, objectclass=objectClass: top, organizationalunit}
Release com.sun.jndi.ldap.LdapClient@5d173

```

您可以通过包含或省略`“com.sun.jndi.ldap.connect.pool”`属性来决定何时何地使用池，从而控制 _ 每个上下文 _ 的池化基础。在前面的示例中，如果在创建第二个初始上下文之前从环境属性中删除了此属性，则第二个初始上下文将不使用池化连接。

LDAP 提供程序通过应用程序的指示跟踪是否正在使用连接。它假定维护打开的上下文句柄的应用程序正在使用该连接。因此，为了使 LDAP 提供程序能够正确管理池化连接，您必须努力在不再需要的上下文中调用 `Context.close（）`。

LDAP 提供程序会自动检测到错误的连接并从池中删除。无论是否使用连接池，上下文以错误连接结束的概率都是相同的。

LDAP 服务提供商维护的连接池的大小可能有限;这在[连接池配置](config.html)部分中有详细描述。启用连接池并且没有可用的池连接时，客户端应用程序将阻塞，等待可用连接。您可以使用`“com.sun.jndi.ldap.connect.timeout”`环境属性来指定等待池连接的时间。如果省略此属性，应用程序将无限期地等待。

此相同属性还用于指定建立 LDAP 连接的超时时间，如[连接创建](create.html#TIMEOUT)部分所述。

## 何时不使用游泳池!!

池连接旨在重用。因此，如果您计划对可能改变底层连接状态的 `Context` 实例执行操作，则不应对该 `Context` 实例使用连接池。例如，如果您计划在 `Context` 实例上调用 Start TLS 扩展操作，或计划更改与安全相关的属性（例如`“java.naming.security.principal”`或`“java.naming.security.protocol”`）在创建初始上下文后，您不应该为 `Context` 实例使用连接池，因为 LDAP 提供程序不跟踪任何此类国家变化。如果在这种情况下使用连接池，则可能会损害应用程序的安全性。