java多线程实践

因为公司业务需要,需要用到多线程。

一种方法是我百度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并发编程实践

转载于:https://my.oschina.net/miaojiangmin/blog/1512287

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值