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

本文详细介绍了如何使用线程池避免Android中Timer的陷阱,通过示例程序展示了ScheduledExecutorService替代Timer执行TimerTask的任务,强调了线程池在异常处理上的优势,即一个线程出错不会影响其他线程的运行。对比了两种方法,得出使用线程池的方法更为优化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


各位看官们,大家好,上一回中咱们说的是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的例子咱们就介绍到这里,欲知后面还有什么例子,且听下回分解!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

talk_8

真诚赞赏,手有余香

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值