因为公司业务需要,需要用到多线程。
一种方法是我百度spring 多线程的解决方案。
配置文件
<bean id="phoenixTaskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<!-- 核心线程数 -->
<property name="corePoolSize" value="${phoenix.core_pool_size}" />
<!-- 最大线程数 -->
<property name="maxPoolSize" value="${phoenix.max_pool_size}" />
<!-- 队列最大长度 -->
<property name="queueCapacity" value="${phoenix.queue_capacity}" />
<!-- 线程池维护线程所允许的空闲时间,默认为60s -->
<property name="keepAliveSeconds" value="${phoenix.keep_alive_seconds}" />
<!-- 线程池对拒绝任务(无线程可用)的处理策略 -->
<property name="rejectedExecutionHandler">
<bean class="java.util.concurrent.ThreadPoolExecutor$CallerRunsPolicy" />
</property>
</bean>
实现类
/**
* 这里采用了Callable接口,是因为这种方式比Runable多了返回,更加适合与单元测试
*/
@Component
@Scope("prototype")
public class IOrderListVer2Task implements Callable<String>, Serializable {
private static final long serialVersionUID = -6626027616177700489L;
@Autowired
private IOrderListVer2Service orderListVer2Service;
private String client;
private String topType;
public void setClient(String client) {
this.client = client;
}
public void setTopType(String topType) {
this.topType = topType;
}
/**
* Computes a result, or throws an exception if unable to do so.
*
* @return computed result
* @throws Exception if unable to compute a result
*/
@Override
public String call() throws Exception {
orderListVer2Service.getOrderList(client,topType);
return "调用成功";
}
}
测试方法
/**
* 比较推荐这种方法,因为这种方法更容易扩展
*/
@Test
public void test(){
// ThreadPoolTaskExecutor poolTaskExecutor = SpringContextUtil.getBean(ThreadPoolTaskExecutor.class);
try {
String[] clients = {"",""};
String[] topTypes = {"",""};
int count = 0;
for(String client:clients){
for(String topType:topTypes){
IOrderListVer2Task task = SpringContextUtil.getBean(IOrderListVer2Task.class);
task.setClient(client);
task.setTopType(topType);
Future<String> future = taskExecutor.submit(task);
System.out.println(future.get());
}
}
}catch (Exception e){
e.printStackTrace();
}
}
另一种方法是不用spring来实现多线程。
/**
* @author zengrong.gzr
* @date 2017/04/18
*/
public class ThreadExecutors {
private static ReentrantLock lock = new ReentrantLock();
private ThreadPoolExecutor threadPoolExecutor;
private static ThreadExecutors instance;
//默认超时两百毫秒
private static final long DEFAULT_TIME_OUT = 200;
public static ThreadExecutors getInstance() {
if (instance == null) {
lock.lock();
try {
if (instance == null) {
instance = new ThreadExecutors();
}
} finally {
lock.unlock();
}
}
return instance;
}
private ThreadExecutors() {
threadPoolExecutor = new ThreadPoolExecutor(100, 500, 100000L, TimeUnit.MILLISECONDS,
new ArrayBlockingQueue<Runnable>(2000), new ThreadPoolExecutor.CallerRunsPolicy());
}
public <T> Future<T> submit(Callable<T> t) {
return threadPoolExecutor.submit(t);
}
public <T> List<Future<T>> invokeAll(List<Callable<T>> tasks, long timeOutMills) {
try {
if (timeOutMills <= 0) {
timeOutMills = DEFAULT_TIME_OUT;
}
return threadPoolExecutor.invokeAll(tasks, timeOutMills, TimeUnit.MILLISECONDS);
} catch (Throwable t) {
return Lists.newArrayList();
}
}
}
在java8中,可以用lambda来简化代码
callables.add(() ->
{
try {
activityPriceService.sendApiAndUpdateActivityPrice(activityPrice);
return activityPrice.getErpCode();
} catch (ApiException e) {
e.printStackTrace();
return "";
}
});
Runnable task3 = () -> {
try {
activityPriceService.sendApiAndUpdateActivityPrice(activityPrice);
} catch (ApiException e) {
e.printStackTrace();
}
};
activityPrices.stream().forEach(activityPrice -> {
callables.add(() -> {
try {
activityPriceService.sendApiAndUpdateActivityPrice(activityPrice);
return activityPrice.getErpCode();
} catch (ApiException e) {
e.printStackTrace();
return "";
}
});
});
//这种方式是可以的
new Thread( () -> System.out.println("In Java8, Lambda expression rocks !!") ).start();
// new Callable<String>( () -> test(activityPrice) ).call();
Callable<Runnable> c = () -> () -> {
System.out.println("Hello from Callable");
};
Callable<String>[] c3 =new Callable[]{ ()->test(activityPrice),
()->"Hello from Callable b", ()->"Hello from Callable c" };
Callable<String> c5 = () -> "Hello from Callable";
Callable<String> c6 = () -> test(activityPrice);
callables.add(() -> test(activityPrice));
//下面是lambda的实现方式,可以参考一下
/*activityPrices.stream().forEach(activityPrice -> {
callables.add(() -> {
try {
activityPriceService.sendApiAndUpdateActivityPrice(activityPrice);
return activityPrice.getErpCode();
} catch (ApiException e) {
e.printStackTrace();
return null;
}
});
});*/
发现有一个博客讲的特别好 Java并发编程实践