线程池和多线程的使用

前言,

刚开始接触到线程和线程池,给我的感觉就是:类名太长、容易出问题、感觉没必要用、估计用不到、难等。所以就不去看,直到项目里真的需要用到多线程和线程池才急忙去恶补了这几个知识,也花了一点时间,最终在项目里实战了一下,又怕出问题所以也去看好些理论知识。觉得很有用所以记录下来以后可能能用得到。

一、首先先了解Java里线程池创建的四种方法

1、newFixedThreadPool(int threads);

固定数目的线程池,当有数据有可能很多有可能很少的情况下,可动态的设定线程数去处理。

2、newCachedThreadPool()

创建一个可缓存的线程池,调用execute将重用以前构造的线程(如果线程可用)。如果没有可用的线程,则创建一个新线程池加到池中。终止从缓存中移除那些已有60秒未使用的线程。

3、newSingleThreadExecutor()

创建一个单线程化的Executor。当一个程序的业务逻辑处理完后到了最后一步储存过程了,而程序只要能确保能正常储存而不需要等储存过程所花费的时间,主线程可以直接返回结果,相当于一个异步处理数据。那么如果储存过程需要执行很长时间,当用户访问过多时,很容易出现调用几个储存过程的线程在后台同时运行时,很有可能同时操作一条数据造成死锁。所以我们就可以通过只能一个线程的线程池去处理这个储存过程。

4、newScheduledThreadPool(int corePoolSize)

创建一个支持定时及周期性的任务执行的线程池,多数情况下可用来替代Timer类。

二、对线程池的操作API

  • shutdown()
    提交任务,开始执行下去,而不去接收处理新的任务。线程池的状态为shutwdown。

  • shutdownNow()
    停止正在执行的任务,开始接收处理其他新的任务。线程池的状态为stop

  • awaitTermination(long timeout, TimeUnit unit)
    等待线程池里线程处理完成或者超时。并且返回一个是否超时的状态。参数给一个时间范围。如果在设定的时间范围内处理完则返回true。

  • isShutdown()
    当调用shutdown()或shutdownNow()方法后返回为true。

  • isTerminated()
    当调用shutdown()方法后,并且所有提交的任务完成后返回为true,如果调用了shutdownNow()方法后,则代表是否成功停止。

  • invokeAll(Collection<? extends Callable> tasks, long timeout, TimeUnit unit)
    给线程池一个任务集合,并且设定一个超时时间,如果在正常时间范围内则返回执行返回结果(和任务列表顺序一样),如果超时未完成则报异常。
    这个例子主要看了这个demo

  • invokeAny(Collection<? extends Callable> tasks)
    正常执行返回结果,否则报异常

  • invokeAny()
    将第一个得到的结果作为返回值,然后立刻终止所有任务。如果设置了超时时间,未超时完成则正常返回结果,如果超时未完成则报超时异常。

三、案例

这是一个简单里案例,但也表现出了线程池的数据处理过程。在实战中根据实际业务合理使用如上的API方法则可以达到一个完整高效的线程池数据处理


       public static void main(String[] args) throws InterruptedException {
        ExecutorService cachedThreadPool = Executors.newFixedThreadPool(20);
        for (int i=0;i<1000;i++){
            int finalI = i;
            cachedThreadPool.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        Thread.sleep(10);
                        te(Thread.currentThread().getName()+"   正在处理:"+ finalI);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
        }
        //提交任务,
        cachedThreadPool.shutdown();
        //等待所有子线程处理完成,超过15秒则不等待,让他异步处理。
        boolean b = cachedThreadPool.awaitTermination(15000, TimeUnit.MILLISECONDS);
    }

    public static void te(String s) throws InterruptedException {
        Thread.sleep(100);
        System.out.println(s);
    }

    

四、普通线程的创建使用。

五、为什么阿里开发手册禁止这样创建线程池

六、尝试了解线程池源码

发布了12 篇原创文章 · 获赞 21 · 访问量 3670
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览