用线程的方式控制并发

来源:互联网 发布:hp1005扫描软件 编辑:程序博客网 时间:2024/05/22 04:35

3步

1.建立线程工厂

package com.champion.itax.common.util;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.ThreadFactory;import java.util.concurrent.atomic.AtomicInteger;/** * 线程池构造工厂 * * @author SHANHY(365384722@QQ.COM) * @date   2015年12月4日 */public class ExecutorServiceFactory {    private static ExecutorServiceFactory executorFactory = new ExecutorServiceFactory();    /**     * 定时任务线程池     */    private ExecutorService executors;    private ExecutorServiceFactory() {    }    /**     * 获取ExecutorServiceFactory     *      * @return     */    public static ExecutorServiceFactory getInstance() {        return executorFactory;    }    /**     * 创建一个线程池,它可安排在给定延迟后运行命令或者定期地执行。     *      * @return     */    public ExecutorService createScheduledThreadPool() {        // CPU个数        int availableProcessors = Runtime.getRuntime().availableProcessors();        // 创建        executors = Executors.newScheduledThreadPool(availableProcessors * 10, getThreadFactory());        return executors;    }    /**     * 创建一个使用单个 worker 线程的     * Executor,以无界队列方式来运行该线程。(注意,如果因为在关闭前的执行期间出现失败而终止了此单个线程,     * 那么如果需要,一个新线程将代替它执行后续的任务)。可保证顺序地执行各个任务,并且在任意给定的时间不会有多个线程是活动的。与其他等效的     * newFixedThreadPool(1) 不同,可保证无需重新配置此方法所返回的执行程序即可使用其他的线程。     *      * @return     */    public ExecutorService createSingleThreadExecutor() {        // 创建        executors = Executors.newSingleThreadExecutor(getThreadFactory());        return executors;    }    /**     * 创建一个可根据需要创建新线程的线程池,但是在以前构造的线程可用时将重用它们。对于执行很多短期异步任务的程序而言,这些线程池通常可提高程序性能。调用     * execute 将重用以前构造的线程(如果线程可用)。如果现有线程没有可用的,则创建一个新线程并添加到池中。终止并从缓存中移除那些已有 60     * 秒钟未被使用的线程。因此,长时间保持空闲的线程池不会使用任何资源。注意,可以使用 ThreadPoolExecutor     * 构造方法创建具有类似属性但细节不同(例如超时参数)的线程池。     *      * @return     */    public ExecutorService createCachedThreadPool() {        // 创建        executors = Executors.newCachedThreadPool(getThreadFactory());        return executors;    }    /**     * 创建一个可重用固定线程数的线程池,以共享的无界队列方式来运行这些线程。在任意点,在大多数 nThreads     * 线程会处于处理任务的活动状态。如果在所有线程处于活动状态时提交附加任务     * ,则在有可用线程之前,附加任务将在队列中等待。如果在关闭前的执行期间由于失败而导致任何线程终止     * ,那么一个新线程将代替它执行后续的任务(如果需要)。在某个线程被显式地关闭之前,池中的线程将一直存在。     *      * @return     */    public ExecutorService createFixedThreadPool(int count) {        // 创建        executors = Executors.newFixedThreadPool(count, getThreadFactory());        return executors;    }    /**     * 获取线程池工厂     *      * @return     */    private ThreadFactory getThreadFactory() {        return new ThreadFactory() {            AtomicInteger sn = new AtomicInteger();            public Thread newThread(Runnable r) {                SecurityManager s = System.getSecurityManager();                ThreadGroup group = (s != null) ? s.getThreadGroup() : Thread.currentThread().getThreadGroup();                Thread t = new Thread(group, r);                t.setName("任务线程 - " + sn.incrementAndGet());                return t;            }        };    }}
2.建立线程池

package com.champion.itax.common.util;import java.util.concurrent.Callable;import java.util.concurrent.ExecutorService;import java.util.concurrent.Future;/** * 线程处理类 * * @author SHANHY(365384722@QQ.COM) * @date   2015年12月4日 */public class ExecutorProcessPool {    private ExecutorService executor;    private static ExecutorProcessPool pool = new ExecutorProcessPool();    private final int threadMax =3;    private ExecutorProcessPool() {        System.out.println("threadMax>>>>>>>" + threadMax);        executor = ExecutorServiceFactory.getInstance().createFixedThreadPool(threadMax);    }    public static ExecutorProcessPool getInstance() {        return pool;    }    /**     * 关闭线程池,这里要说明的是:调用关闭线程池方法后,线程池会执行完队列中的所有任务才退出     *      * @author SHANHY     * @date   2015年12月4日     */    public void shutdown(){        executor.shutdown();    }    /**     * 提交任务到线程池,可以接收线程返回值     *      * @param task     * @return     * @author SHANHY     * @date   2015年12月4日     */    public Future<?> submit(Runnable task) {        return executor.submit(task);    }    /**     * 提交任务到线程池,可以接收线程返回值     *      * @param task     * @return     * @author SHANHY     * @date   2015年12月4日     */    public Future<?> submit(Callable<?> task) {        return executor.submit(task);    }    /**     * 直接提交任务到线程池,无返回值     *      * @param task     * @author SHANHY     * @date   2015年12月4日     */    public void execute(Runnable task){        executor.execute(task);    }}
3.测试

package com.champion.itax.common.util;import java.util.concurrent.Callable;import java.util.concurrent.Future;import java.util.concurrent.TimeUnit;/** * 测试类 * */public class ExecutorTest {    public static void main(String[] args) {           ExecutorProcessPool pool = ExecutorProcessPool.getInstance();          // for (int i = 0; i < 200; i++) {            //   Future<?> future = pool.submit(new ExcuteTask1(i+""));//           try {//               如果接收线程返回值,future.get() 会阻塞,如果这样写就是一个线程一个线程执行。所以非特殊情况不建议使用接收返回值的。//               System.out.println(future.get());   //           } catch (Exception e) {//               e.printStackTrace();//           }         //  }                                pool.execute(new MakeCreditRport("第一个"));                  //关闭线程池,如果是需要长期运行的线程池,不用调用该方法。           //监听程序退出的时候最好执行一下。           pool.shutdown();       }       /**        * 执行任务,实现Runable方式        */       static class MakeCreditRport implements Runnable {           private String taskName;           public MakeCreditRport(String taskName) {              this.taskName = taskName;           }           public void run() {            //保存申请人贷款申请表           }       }              static class ExcuteTask3 implements Runnable {           private String taskName;           public ExcuteTask3(String taskName) {               this.taskName = taskName;           }           public void run() {               try {                  // TimeUnit.MILLISECONDS.sleep((int)(Math.random() * 1000));// 1000毫秒以内的随机数,模拟业务逻辑处理             while(true){                TimeUnit.MILLISECONDS.sleep((int)(Math.random() * 1000));             }               } catch (Exception e) {                   e.printStackTrace();               }           }       }              static class ExcuteTask4 implements Runnable {           private String taskName;           public ExcuteTask4(String taskName) {               this.taskName = taskName;           }           public void run() {               try {                   System.out.println("第三个线程");               } catch (Exception e) {                   e.printStackTrace();               }           }       }}

原创粉丝点击