package com.ustcinfo.rpc.client; import java.util.ArrayList; import java.util.List; import java.util.Random; import java.util.concurrent.Callable; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.FutureTask; public abstract class AbstractClientFactory implements ClientFactory { // Cache client private static ConcurrentHashMap<String, FutureTask<List<Client>>> clients = new ConcurrentHashMap<String, FutureTask<List<Client>>>(); public Client get(final String targetIP, final int targetPort, final int connectTimeout) throws Exception { return get(targetIP, targetPort, connectTimeout, 1); } public Client get(final String targetIP, final int targetPort, final int connectTimeout, final int clientNums) throws Exception { String key = targetIP + ":" + targetPort; if (clients.containsKey(key)) { if (clientNums == 1) { return clients.get(key).get().get(0); } else { Random random = new Random(); return clients.get(key).get().get(random.nextInt(clientNums)); } } else { final String cacheKey = key; FutureTask<List<Client>> task = new FutureTask<List<Client>>( new Callable<List<Client>>() { public List<Client> call() throws Exception { List<Client> clients = new ArrayList<Client>( clientNums); for (int i = 0; i < clientNums; i++) { clients.add(createClient(targetIP, targetPort, connectTimeout, cacheKey)); } return clients; } }); FutureTask<List<Client>> currentTask = clients.putIfAbsent(key,task); if (currentTask == null) { task.run(); } else { task = currentTask; } if (clientNums == 1) return task.get().get(0); else { Random random = new Random(); return task.get().get(random.nextInt(clientNums)); } } } public void removeClient(String key) { try { clients.remove(key); } catch (Exception e) { // IGNORE } } public static ClientFactory getInstance() { throw new UnsupportedOperationException( "should be implemented by true class"); } protected abstract Client createClient(String targetIP, int targetPort, int connectTimeout, String key) throws Exception; }