结上一篇 多线程的简单介绍 http://www.cnblogs.com/duanxiaojun/p/6595847.htmlhtml
在上一讲中我主要是对多线程学习这个系列作了一个大体的学习计划,而后对实现线程的两种方式作了介绍,可是在上一讲中漏说了一点就是为何java要提供集成Thread和实现runnable接口这两种方式来实现线程,这个问题是我在面试的时候被问到的,很惋惜以前从没了解过为何-------这也给本身一个教训就是之后学什么东西要试着去问本身为何是这样的,人家为何这样去设计。好了针对这个问题在我查阅了不少资料后得出的是以下的解释:java
首先说一下,咱们知道java的集成只能是单继承,不能多集成,这样的话就会有缺陷,好比想增长一个功能的时候必需要去修改基类。而实现runnable接口的这种方式能够很好的解决java不能多继承致使的缺陷。这是第一个缘由。面试
再说第二个,咱们知道实现runnable接口的方式代码的写法是这样的:new Thread(new runnable(){ public void run(){ ....}})。在这种状况下咱们能够看到其实整个的runnable对象中的代码能够被多个Thread对象实例所使用共享,这样就能够解决一个多个线程处理同一资源的状况。作到了线程安全。在这里我觉着有必要经过一个代码的方式来解释一下第二个优势是如何实现的。咱们拿一个卖火车票的例子,固然也能够是其余的有惟一资源的例子均可以。下面先看代码以下和对代码的解释:安全
上面第对这个优势的一个代码的展现。多线程
好了 除了这两个外 咱们说其实在真正的项目中咱们使用实现接口的方式是比较多的。函数
说到这里好像没有说线程的一些状态,线程有以下的几种状态:建立,就绪,堵塞,终止。对这四种状态你们应该比较熟悉吧,这时候我又想起来一个面试的时候被问的,就是说说sleep和wait有什么区别,其实从字面意思也不难理解,sleep是睡眠,睡指定时候后就本身到就绪队列中等待这cpu时间片的轮询到的时候就占用cpu资源开始执行。而wait是等待,知道有人去主动的唤醒他notify或者唤醒所有notifyAll,在等待的时候是不占用资源的,也就是资源已经被释放。其余的我想应该没什么别的了。主要是看面试官想问什么了。学习
好了上面是对上一篇的一个总结和补充,下面开始今天的有关javaTimer定时器的学习。线程
首先来讲一下Timer是怎么工做的,Timer 是按照必定的时间段或者一个时间点根据定时的定时任务进行执行的。设计
Timer这个java提供的定时器有以下的特色:htm
① 他是一个单线程的,也就是你启动一个Timer定时器就是启动了一个线程。
② Timer定时器默认的状况下不是守护线程,可是能够经过构造参数设置为守护线程,守护线程在没有其余线程的状况下本身会挂掉。
③ 使用Timer定时器的时候 要跟一个TimerTask定时任务结合来使用。并且TimerTask其实底层就是一个队列,在TimerTask中增长的任务会在定时器这个线程里面挨个的执行。TimerTask也有本身的cannel取消等方法。
④ TimerTask中的run方法没法抛出,因此要进行try catch捕获,若是其中任何一个任务发生异常没有被捕获,则其余任务也将被终止
说了这些概念,咱们先来一个代码例子来看看是这么执行的吧。
咱们看到TImer定时器这个类有两个schedule方法。其中都有的就是一个TimerTask这个任务。我对这两个方法进行了一个总结-----网友提供。。
首先咱们看一下Timer这个类的构造函数,由于咱们知道咱们再使用Timer这个类的时候咱们只是建立了一个Timer对象,并无像Thread那样主动的去调用start方法。因此我想答应也应该明白咱们定时器的启动是在构造函数中作的,没错,从源码中咱们能够得道验证:
哈哈哈 没错吧,其实咱们是Timer是一个单独的线程,从第152行咱们就能够看到,咱们能够设置线程的名称,能够设置是不是守护线程,而后调用start方法定时器就起做用了。可是并不会当即执行。线程调用start后也不会当即执行,这在上一篇中已经有说到了,他实际上是把当前的线程示例放到了一个线程组中等待被执行。
哪咱们就看他是如何调度的也就是schdule是如何执行的呢。
这里咱们补充一下,queue是一个TaskQueue,
好了对Timer的介绍今天就到这里吧,若有没有说到的请各位评论一下,你们一块学习。