Java学习札记16:浅析 Thread 类中的 start() 和 run() 方法

来源:互联网 发布:java final 变量举例 编辑:程序博客网 时间:2024/05/01 07:19

PART 1


1、start(): 

用 start() 方法来启动线程,真正实现了多线程运行,这时无需等待 run() 方法中的代码执行完毕而直接继续执行下面的代码。通过调用 Thread 类的 start() 方法来启动一个线程,这时此线程处于就绪(可运行)状态,并没有运行,一旦得到 CPU 时间片,就开始执行 run() 方法,这里的方法 run() 称为线程体,它包含了要执行的这个线程的内容,run() 方法运行结束,此线程随即终止。 


2、run(): 

run() 方法只是 Thread 类的一个普通方法而已,如果直接调用 run() 方法,程序中依然只有主线程这一个线程,其程序执行路径还是只有一条,还是要顺序执行,还是要等待 run() 方法体执行完毕后才可继续执行下面的代码,这样就没有达到写线程的目的。 


总结:调用 start() 方法方可启动线程,而 run() 方法只是 Thread 类的一个普通方法调用,还是在主线程里执行。


线程状态说明:

线程状态从大的方面来说,可归结为:初始状态、可运行状态、不可运行状态和消亡状态,具体可细分为7个状态,说明如下: 
1、线程的实现有两种方式,一是继承 Thread 类,二是实现 Runnable 接口,但不管怎样,当我们 new 了 Thread实例后,线程就进入了初始状态; 

2、当该对象调用了 start() 方法,就进入可运行状态; 

3、进入可运行状态后,当该对象被操作系统选中,获得 CPU 时间片就会进入运行状态; 

4、进入运行状态后情况就比较多,大致有如下情形:

    · run() 方法或 main() 方法结束后,线程就进入终止状态;

    · 当线程调用了自身的 sleep() 方法或其他线程的 join() 方法,就会进入阻塞状态(该状态既停止当前线程,但并不释放所占有的资源)。当 sleep() 结束或 join() 结束后,该线程进入可运行状态,继续等待 OS 分配时间片;

    · 当线程刚进入可运行状态(注意,还没运行),发现将要调用的资源被锁牢(synchroniza,lock),将会立即进入锁池状态,等待获取锁标记(这时的锁池里也许已经有了其他线程在等待获取锁标记,这时它们处于队列状态,既先到先得),一旦线程获得锁标记后,就转入可运行状态,等待 OS 分配 CPU 时间片;

    · 当线程调用 wait() 方法后会进入等待队列(进入这个状态会释放所占有的所有资源,与阻塞状态不同),进入这个状态后,是不能自动唤醒的,必须依靠其他线程调用 notify() 或 notifyAll() 方法才能被唤醒(由于 notify() 只是唤醒一个线程,但我们由不能确定具体唤醒的是哪一个线程,也许我们需要唤醒的线程不能够被唤醒,因此在实际使用时,一般都用 notifyAll() 方法,唤醒有所线程),线程被唤醒后会进入锁池,等待获取锁标记;

    · 当线程调用 stop() 方法,即可使线程进入消亡状态,但是由于 stop() 方法是不安全的,不鼓励使用,大家可以通过 run()方法里的条件变通实现线程的 stop() 方法。



PART 2


多线程原理

相当于玩游戏机,只有一个游戏机(CPU),可是有很多人要玩,于是,start() 是排队!等 CPU 选中你就是轮到你,你就 run(),当 CPU 运行的时间片执行完,这个线程就继续排队,等待下一次的run()。

记住:多线程就是分时利用 CPU,宏观上让所有线程一起执行 ,也叫做并发执行。


在 Java 当中,线程通常都有五种状态:创建、就绪、运行、阻塞和死亡。

    第一是创建状态。在生成线程对象时,并没有调用该对象的 start() 方法,这时线程处于创建状态。

    第二是就绪状态。当调用了线程对象的 start() 方法之后,该线程就进入了就绪状态,但是此时线程调度程序还没有把该线程设置为当前线程,此时处于就绪状态。在线程运行之后,从等待或者睡眠中回来之后,也会处于就绪状态。

    第三是运行状态。线程调度程序将处于就绪状态的线程设置为当前线程,此时线程就进入了运行状态,开始运行 run() 方法当中的代码。

    第四是阻塞状态。线程正在运行的时候,被暂停,通常是为了等待某个时间的发生(比如说某项资源就绪)之后再继续运行。sleep()、suspend()、wait() 等方法都可能导致线程阻塞。

    第五是死亡状态。如果一个线程的 run() 方法执行结束或者调用 stop() 方法后,该线程就会死亡。对于已经死亡的线程,无法再使用 start() 方法令其进入就绪。



参考资料:

http://blog.sina.com.cn/s/blog_5db5a8b2010144bf.html

http://blog.csdn.net/xuxurui007/article/details/7685076




原创粉丝点击