一起Talk Android吧(第三百七十三回:多线程版Timer)

Posted talk_8

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一起Talk Android吧(第三百七十三回:多线程版Timer)相关的知识,希望对你有一定的参考价值。

文章目录


各位看官们,大家好,上一回中咱们说的是android中Timer陷阱的例子,这一回中咱们介绍的例子是多线程版Timer。闲话休提,言归正转。让我们一起Talk Android吧!

看官们,我们在上一章回中提到了使用Timer时的陷阱,而且介绍了避开陷阱的方法:创建两个Timer。不过此方法不是最优方法,本章回中我们将介绍另外一种好的方法:使用线程池来解决Timer的陷阱

使用方法

大家还记得我们在介绍线程池知识时提到过ExecutorService接口代表线程池,不过我们不直接使用它,而是使用:ScheduledExecutorService接口,此接口继承了ExecutorService接口,因此我们也可以把它当作线程池,下面是具体的使用方法:

  • 1.使用Executors的静态方法创建线程池;
  • 2.创建两个TimerTask任务,并且把它们添加到线程池中;
  • 3.停止Timer任务并且释释放线程池;

示例程序

下面是示例程序,请大家参考:

public class TimerEx 

    public static void main(String[] args) 
        //1.使用Executors的静态方法创建线程池;
        ScheduledExecutorService timerThreadPool = Executors.newScheduledThreadPool(2);

        TimerTask timerTask111 = new TimerTask() 
            @Override
            public void run() 
                String str = null;
                System.out.println("111 running");
                //str.length();
            
        ;

        TimerTask timerTask222 = new TimerTask() 
            @Override
            public void run() 
                System.out.println("222 running");
            
        ;

        //2.创建两个TimerTask任务,并且把它们添加到线程池中;
        timerThreadPool.scheduleAtFixedRate(timerTask111,0,2, TimeUnit.SECONDS);
        timerThreadPool.scheduleAtFixedRate(timerTask222,0,2, TimeUnit.SECONDS);

        try 
            TimeUnit.SECONDS.sleep(5);
         catch (InterruptedException e) 
            e.printStackTrace();
        

        //3.停止Timer任务并且释放线程池;下面是示例程序,请大家参考:
        timerTask111.cancel();
        timerTask222.cancel();
        timerThreadPool.shutdown();

        System.out.println("close thread pool.");
    

此程序和前面章回的程序类似,不同之处在于前面章回的程序中使用Timer来执行TimerTask任务,此程序使用线程池来执行TimerTask任务,编译并且运行上面的程序可以得到以下结果:

111 running
222 running
111 running
222 running
111 running
222 running
close thread pool.

从程序的运行结果中可以看到,两个任务每隔一段时间(程序中设定为2s)运行一次,此时主线程在sleep,运行三次后主线程sleep结束(5s后结束)并且取消设定的Timer(可以看作是销毁线程池),此时这两个任务停止运行。

接下来我们打开代码中被注释的程序,再次运行时会因访问空指针而产生异常,具体的结果如下:

111 running
222 running
222 running
222 running
close thread pool.

从上面的运行结果中可以看到,前一个线程发生异常后会停止运行,但是它不会阻塞后一个线程,后一个线程一直按照设置的时间去运行直到被主线程停止后才结束运行。

对比总结

对比以上两种运行结果可以得出结论:线程池中某个线程发生异常时不会阻塞其它线程。

我们与上一章回中的内容对比后就会发现:如果想避开Timer中的陷阱,那么可以再创建一个Timer,让不同的Timer运行不同的TimerTask任务。这相当于创建了两个线程池;如果使用线程池来运行TimerTask任务,既可以避开Timer中的陷阱,又不需要创建额外的线程池。这种方法明显要好一些。

看官们,关于Android中多线程版本Timer的例子咱们就介绍到这里,欲知后面还有什么例子,且听下回分解!

以上是关于一起Talk Android吧(第三百七十三回:多线程版Timer)的主要内容,如果未能解决你的问题,请参考以下文章

一起Talk Android吧(第三百七十四回:多线程之大结局)

一起Talk Android吧(第三百七十回:多线程之线程池回顾)

一起Talk Android吧(第三百七十二回:Timer的陷阱)

一起Talk Android吧(第三百七十一回:多线程之线程池扩展)

一起Talk Android吧(第三百七十五回:如何使用ViewPager2)

一起Talk Android吧(第三百七十六回:如何使用TabLayout)