Java tutorial
/******************************************************************************* * Copyright 2015 htd0324@gmail.com * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************/ package com.laudandjolynn.mytv.proxy; import java.util.ArrayList; import java.util.List; import java.util.concurrent.Callable; import java.util.concurrent.CompletionService; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorCompletionService; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.ThreadFactory; import org.apache.commons.lang3.concurrent.BasicThreadFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.laudandjolynn.mytv.model.Proxy; import com.laudandjolynn.mytv.utils.Constant; /** * @author: Laud * @email: htd0324@gmail.com * @date: 2015428 ?5:47:56 * @copyright: www.laudandjolynn.com */ public class MyTvProxyManager { private final static Logger logger = LoggerFactory.getLogger(MyTvProxyManager.class); public final static String PROXY_ANONYMOUS_HIGH = ""; public final static String PROXY_TYPE_SOCK = "scok5"; private final static String LOCALHOST = "localhost"; private final ConcurrentLinkedQueue<Proxy> PROXY_QUEUE = new ConcurrentLinkedQueue<Proxy>(); private final static Proxy LOCALHOST_PROXY = new Proxy(LOCALHOST, 80); private List<ProxyProvider> providerList = new ArrayList<ProxyProvider>(); private MyTvProxyManager() { } private final static class MyTvProxySingletonHolder { private final static MyTvProxyManager MY_TV_PROXY = new MyTvProxyManager(); } public static MyTvProxyManager getInstance() { return MyTvProxySingletonHolder.MY_TV_PROXY; } public void prepareProxies(ProxyProvider... providers) { int length = providers == null ? 0 : providers.length; if (length > 0) { int maxThreadNum = Constant.CPU_PROCESSOR_NUM; ThreadFactory threadFactory = new BasicThreadFactory.Builder().namingPattern("MyTv_Find_Proxies_%d") .build(); ExecutorService executorService = Executors .newFixedThreadPool(length > maxThreadNum ? maxThreadNum : length, threadFactory); CompletionService<List<Proxy>> completionService = new ExecutorCompletionService<List<Proxy>>( executorService); providerList.clear(); for (int i = 0; i < length; i++) { final ProxyProvider provider = providers[i]; providerList.add(provider); completionService.submit(new Callable<List<Proxy>>() { @Override public List<Proxy> call() throws Exception { return provider.getProxies(); } }); } executorService.shutdown(); int count = 0; List<Proxy> resultList = new ArrayList<Proxy>(); while (count < length) { try { Future<List<Proxy>> future = completionService.take(); List<Proxy> proxies = future.get(); if (proxies != null) { resultList.addAll(proxies); } } catch (InterruptedException e) { logger.error("get proxies thread has interrupted.", e); } catch (ExecutionException e) { logger.error("get proxies thread has execution fail.", e); } count++; } resultList.add(LOCALHOST_PROXY); PROXY_QUEUE.clear(); PROXY_QUEUE.addAll(resultList); } } /** * ?? */ public void refresh() { int size = providerList.size(); ProxyProvider[] providers = new ProxyProvider[size]; prepareProxies(providerList.toArray(providers)); } public int getProxySize() { return PROXY_QUEUE.size(); } public Proxy pickProxy() { Proxy proxy = PROXY_QUEUE.poll(); if (proxy == null) { return null; } PROXY_QUEUE.offer(proxy); if (LOCALHOST.equals(proxy.getIp())) { return null; } return proxy; } }