浅谈对java线程池的理解二

    xiaoxiao2021-03-26  26

    在《浅谈对java线程池的理解一》中介绍了线程池的创建,一般利用Executors类提供的方法进行创建就可满足需求了,当然如果要想进一步创建更加自定义化的线程池,可以利用ThreadPoolService的构造方法进行创建,这里不再详细介绍了,感兴趣的同学可以自行查阅API。

    本篇主要讲述一下线程池的使用。我们先看一下线程池相关几个核心类的类图:

    由上面类图可以看出,ExecutorService接口继承Executor接口,而ExecutorService有几个实现类,比如ScheduleExecutorService和ThreadPoolService,总而言之,我们声明的线程池都是实现了ExecutorService接口,几个重要的经常使用的方法有下面几个:

    1、        execute()

    该方法是线程池运行线程的方法,该方法只是发出一个自行的命令,至于什么时候线程开始运行不知道,java API的描述是“at some time in the future(在将来的某个时间)”。用法如下:

    ExecutorServiceexecutorService = Executors.newSingleThreadExecutor();

            Log.d("thread","beginexecute...");

            executorService.execute(new Runnable(){

                @Override

                public void run() {

                   Log.d("thread","runnable is running!");

                }

            });

    运行结果如下:

    2、        submit()

    该方法也是线程池执行线程的方法,和execute方法类似,但是该方法相比于execute方法的一个优点就是可以返回线程执行的结果。该方法有3种传参方式:

    ⑴ Future<?>submit(Runnable task)

    该方法等同于execute方法

    ⑵Future<T>submit(Callable<T> task)

    该方法的参数是一个Callable对象,用法如下例子所示:

    ExecutorServiceexecutorService = Executors.newFixedThreadPool(2);

            Callable<String> callable1 = newCallable<String>() {

                @Override

                public String call() throwsException {

                   Log.d("zhouyudong","call1.call"+Thread.currentThread().getName());

                    Thread.sleep(2000);

                   Log.d("zhouyudong","call1.call after sleep");

                    return "first over";

                }

            };

     

            Callable<String> callable2 = newCallable<String>() {

                @Override

                public String call() throwsException {

                   Log.d("zhouyudong","call2.call"+Thread.currentThread().getName());

                    Thread.sleep(4000);

                   Log.d("zhouyudong","call2.call after sleep");

                    return "second over";

                }

            };

     

            Callable<String> callable3 = newCallable<String>() {

                @Override

                public String call() throws Exception {

                   Log.d("zhouyudong","call3.call"+Thread.currentThread().getName());

    //                Thread.sleep(4000);

                    return "third over";

                }

            };

     

            List<Future<String>>futureList = new ArrayList<>();

           futureList.add(executorService.submit(callable1));

           futureList.add(executorService.submit(callable2));

           futureList.add(executorService.submit(callable3));

           

            for(Future<String>future:futureList)

            {

                try {

                   Log.d("zhouyudong",future.get());

                } catch (InterruptedException e) {

                    e.printStackTrace();

                } catch (ExecutionException e) {

                    e.printStackTrace();

                }

            }

    该方法可以获取任务执行结果的返回值,返回值在Future<T>中,通过get方法可以获取,但是如果线程没有执行完毕,get方法会被阻塞。

    ⑶Future<T>submit(Runnable task, T result)

    该方法就是相当于给Runnable的run方法增加一个返回值,该返回值就是result

    3、        shutdown()

    该方法会把线程池的状态置为SHUTDOWN状态,分两种情况考虑,一是线程池的任务队列为空时,调用shutdown方法之后,正在执行的任务会被停止,并且不再会接受新任务;二是线程池中有等待的任务,那么调用shutdown方法后,仅有的作用就是再会接受新任务

    4、        shutdownNow()

    该方法会把线程池的状态置为STOP状态,并试图停止所有正在执行的线程,不再处理还在池队列中等待的任务,当然,它会返回那些未执行的任务。

    5、        isShutdown()

    在调用shutdown或者shutdownNow方法之后,该方法返回true。

    6、        isTerminate()

    当调用shutdown()或者或者shutdownNow方法后,并且所有提交的任务完成后返回为true。

     

     

    转载请注明原文地址: https://ju.6miu.com/read-350315.html

    最新回复(0)