==>两种创建线程方式的比较:
实现Runnble接口的优缺点分别如下:
从面向对象的角度来看,Thread类是一个虚拟处理机严格的封装,因此只有当处理机模型修改或扩展时,才应该继承该类。
由于Java 技术只允许单一继承,所以如果已经继承了Thread类,就不能再继承其他任何类,这会使用户只能采用实现Runnable接口的方式创建线程。
继承Thread类的优缺点分别如下:
当一个run()方法体现在继承Thread的类中,用this指向实际控制运行的Thread实例,因此,代码不再需要使用如下控制:Thread.currenThread().sleep(),而可以简单地使用:Thread.sleep()。继承Thread类方式使代码变的简单易读。
==>生命周期:
线程的4个主要周期状态是“创建”、“可执行”、“非可执行”和“消亡”,状态间的关系如图所示:
- 创建
当实例化一个Thread对象并执行start()方法后,线程进入“可执行”状态,开始执行,虽然多线程给用户一种同时执行的假象,但事实上在同一时间点上,只有一个线程在执行,只是线程之间转换的动作很快,所以看起来如同时执行一样。 - 可执行
当线程启用start()方法后,进入“可执行”状态,执行用户覆写的run()方法。当一个线程进入“可执行”状态下,并不代表它可以一直执行到run()结束为止,事实上它只是加入此应用程序执行安排的队列中,正如前文中提到的,这个线程加入了这个进程的线程执行队列中,对于大多数计算机而言,只有一个处理器,无法使多个线程同时执行,这时需要合理安排线程执行计划,让那些处于“可执行”状态下的线程合理分享CPU资源。所以,一个处在“可执行”状态下的线程,实际上可能正在等待取得CPU时间,也就是等候执行权,在何时给予线程执行权,则由Java虚拟机决定,同时也由线程的优先级来决定。 - 非可执行
在“可执行”状态下,线程可能被执行完毕,也可能没有执行完毕,处于等待执行权的队列中,当使线程离开“可执行”状态下的等待队列时,线程进入“非可执行”状态。可以使用Thread类中的wait()、sleep()方法使线程进入“非可执行”状态。
当线程进入“非可执行”状态下,CPU不分配时间片给这个线程,若希望线程回到“可执行”状态时,可以使用notify()方法、notifyAll()方法以及interrupt()方法。 - 消亡
当run()方法执行完毕后,线程自动消亡,当Thread类调用start()方法时,Java虚拟机自动调用它的run()方法,而当run()方法结束时,该Thread会自动终止。以前Thread类中存在一个停止线程的方法stop(),不过现在废弃了,因为调用这个方法,很容易使程序进入不稳定状态。