|
63 | 63 | import java.net.URISyntaxException; |
64 | 64 | import java.util.ArrayList; |
65 | 65 | import java.util.Collection; |
66 | | -import java.util.HashMap; |
67 | 66 | import java.util.HashSet; |
68 | 67 | import java.util.List; |
69 | | -import java.util.Map; |
| 68 | +import java.util.concurrent.ConcurrentHashMap; |
| 69 | +import java.util.concurrent.ConcurrentMap; |
70 | 70 | import java.util.concurrent.Executor; |
71 | 71 | import java.util.concurrent.ExecutorService; |
72 | 72 | import java.util.concurrent.ScheduledExecutorService; |
@@ -139,14 +139,16 @@ public final class ManagedChannelImpl extends ManagedChannel implements WithLogI |
139 | 139 | private LoadBalancer<ClientTransport> loadBalancer; |
140 | 140 |
|
141 | 141 | /** |
142 | | - * Maps EquivalentAddressGroups to transports for that server. |
| 142 | + * Maps EquivalentAddressGroups to transports for that server. "lock" must be held when mutating. |
143 | 143 | */ |
144 | | - @GuardedBy("lock") |
145 | | - private final Map<EquivalentAddressGroup, TransportSet> transports = |
146 | | - new HashMap<EquivalentAddressGroup, TransportSet>(); |
| 144 | + // Even though we set a concurrency level of 1, this is better than Collections.synchronizedMap |
| 145 | + // because it doesn't need to acquire a lock for reads. |
| 146 | + private final ConcurrentMap<EquivalentAddressGroup, TransportSet> transports = |
| 147 | + new ConcurrentHashMap<EquivalentAddressGroup, TransportSet>(16, .75f, 1); |
147 | 148 |
|
148 | 149 | /** |
149 | | - * TransportSets that are shutdown (but not yet terminated) due to channel idleness. |
| 150 | + * TransportSets that are shutdown (but not yet terminated) due to channel idleness or channel |
| 151 | + * shut down. |
150 | 152 | */ |
151 | 153 | @GuardedBy("lock") |
152 | 154 | private final HashSet<TransportSet> decommissionedTransports = new HashSet<TransportSet>(); |
@@ -425,6 +427,8 @@ public ManagedChannelImpl shutdown() { |
425 | 427 | maybeTerminateChannel(); |
426 | 428 | if (!terminated) { |
427 | 429 | transportsCopy.addAll(transports.values()); |
| 430 | + transports.clear(); |
| 431 | + decommissionedTransports.addAll(transportsCopy); |
428 | 432 | delayedTransportsCopy.addAll(delayedTransports); |
429 | 433 | oobTransportsCopy.addAll(oobTransports); |
430 | 434 | } |
@@ -472,6 +476,7 @@ public ManagedChannelImpl shutdownNow() { |
472 | 476 | List<OobTransportProviderImpl> oobTransportsCopy; |
473 | 477 | synchronized (lock) { |
474 | 478 | transportsCopy = new ArrayList<TransportSet>(transports.values()); |
| 479 | + transportsCopy.addAll(decommissionedTransports); |
475 | 480 | delayedTransportsCopy = new ArrayList<DelayedClientTransport>(delayedTransports); |
476 | 481 | oobTransportsCopy = new ArrayList<OobTransportProviderImpl>(oobTransports); |
477 | 482 | } |
@@ -589,7 +594,10 @@ public void updateRetainedTransports(Collection<EquivalentAddressGroup> addrs) { |
589 | 594 | @Override |
590 | 595 | public ClientTransport getTransport(final EquivalentAddressGroup addressGroup) { |
591 | 596 | checkNotNull(addressGroup, "addressGroup"); |
592 | | - TransportSet ts; |
| 597 | + TransportSet ts = transports.get(addressGroup); |
| 598 | + if (ts != null) { |
| 599 | + return ts.obtainActiveTransport(); |
| 600 | + } |
593 | 601 | synchronized (lock) { |
594 | 602 | if (shutdown) { |
595 | 603 | return SHUTDOWN_TRANSPORT; |
|
0 commit comments