黑马程序员_java线程进阶 (一)

2014-11-24 11:39:20 · 作者: · 浏览: 26

一、线程的生命周期
这里所说的线程的生命周期,也是根据Thread类里面的方法来定义的。JDK API 1.6里和生命周期有关的方法有一些几个:
1、interrupt():中断线程。
2、interrupted():测试当前线程是否已经中断。
3、isInterrupted():测试线程是否已经中断。
4、join():等待该线程终止。
5、join(long millis):等待该线程终止的时间最长为 millis 毫秒。
6、join(long millis, int nanos):等待该线程终止的时间最长为 millis 毫秒 + nanos 纳秒。
7、run():如果该线程是使用独立的 Runnable 运行对象构造的,则调用该 Runnable 对象的 run 方法;否则,该方法不执行任何操作并返回。
8、sleep(long millis, int nanos): 在指定的毫秒数加指定的纳秒数内让当前正在执行的线程休眠(暂停执行),此操作受到系统计时器和调度程序精度和准确性的影响。
9、start(): 使该线程开始执行;Java 虚拟机调用该线程的 run 方法。
10、yield():暂停当前正在执行的线程对象,并执行其他线程。
11、isAlive(): 测试线程是否处于活动状态。
对于官方已经弃用不建议使用的方法没有列举,从这些方法中可以看出,目前的java线程生命周期有开始运行、睡眠、等待、中断、暂停,但是没有了重新开始。Java的线程是不能重启的,也就是说,当线程的run()方法执行到最后一行,退出之后,这个线程就结束了,不能再通过start()方法重启启动这个线程,只能重新构造一个线程对象,再调用其start()方法来启动,但这个对象和原来那个对象已经不同了。


线程在建立后并不马上执行run方法中的代码,而是处于等待状态。线程处于等待状态时,可以通过Thread类的方法来设置线程不各种属性,如线程的优先级(setPriority)、线程名(setName)和线程的类型(setDaemon)等。当调用start方法后,线程开始执行run方法中的代码。线程进入运行状态。可以通过Thread类的isAlive方法来判断线程是否处于运行状态。当线程处于运行状态时,isAlive返回true,当isAlive返回false时,可能线程处于等待状态,也可能处于停止状态。
[java]
public class LifeCycle extends Thread
{
public void run()
{
int n = 0;
while ((++n) < 1000);
}

public static void main(String[] args) throws Exception
{
LifeCycle thread1 = new LifeCycle();
System.out.println("isAlive: " + thread1.isAlive());
thread1.start();
System.out.println("isAlive: " + thread1.isAlive());
thread1.join(); // 等线程thread1结束后再继续执行
System.out.println("thread1已经结束!");
System.out.println("isAlive: " + thread1.isAlive());
}
}

public class LifeCycle extends Thread
{
public void run()
{
int n = 0;
while ((++n) < 1000);
}

public static void main(String[] args) throws Exception
{
LifeCycle thread1 = new LifeCycle();
System.out.println("isAlive: " + thread1.isAlive());
thread1.start();
System.out.println("isAlive: " + thread1.isAlive());
thread1.join(); // 等线程thread1结束后再继续执行
System.out.println("thread1已经结束!");
System.out.println("isAlive: " + thread1.isAlive());
}
} 要注意一下,在上面的代码中使用了join方法,这个方法的主要功能是保证线程的run方法完成后程序才继续运行,上面代码的运行结果:
isAlive: false
isAlive: true
thread1已经结束!
isAlive: false


一但线程开始执行run方法,就会一直到这个run方法执行完成这个线程才退出。但在线程执行的过程中,可以通过两个方法使线程暂时停止执行。这两个方法是yield和sleep。thread.yield()在多线程程序中,为了防止某线程独占CPU资源(这样其它的线程就得不到"响应"了).可以让当前执行的线程"休息"一下.但是这种thread.yield() 调用,并不保证下一个运行的线程就一定不是该线程.而使用sleep使线程休眠后,只能在设定的时间后使线程处于就绪状态(在线程休眠结束后,线程不一定会马上执行,只是进入了就绪状态,等待着系统进行调度)。在使用sleep时要注意,不能在一个线程中来休眠另一个线程。如main方法中使用thread.sleep(2000)方法是无法使thread线程休眠2秒的,而只能使主线程休眠2秒。在使用sleep方法时有四点需要注意:

1. sleep方法有两个重载形式,其中一个重载形式不仅可以设毫秒,而且还可以设纳秒(1,000,000纳秒等于1毫秒)。但大多数操作系统平台上的Java虚拟机都无法精确到纳秒,因此,如果对sleep设置了纳秒,Java虚拟机将取最接近这个值的毫秒。

2. 在使用sleep方法时必须使用throws或try{...}catch{...}。因为run方法无法使用throws,所以只能使用try{...}catch{...}。当在线程休眠的过程中,使用interrupt方法(这个方法将在2.3.3中讨论)中断线程时sleep会抛出一个InterruptedException异常。


3. sleep()使当前线程进入停滞状态,所以执行sleep()的线程在指定的时间内肯定不会执行;yield()只是使当前线程重新回到可执行状态,所以执行yield()的线程有可能在进入到可执行状态后马上又被执行。

4. sleep()可使优先级低的线程得到执行的机会,当然也可以让同优先