人有生老病死,线程也同样要经历开始、运行、挂起、停止四种不同的状态。
这四种状态都可以通过Thread类中的方法进行控制。
下面是Thread类中和这四种状态相关的方法。
1.开始状态:
public void start();
public void run();
2.挂起和唤醒线程:
public void resume();
public void suspend();
public static void sleep(long millis);
public static void sleep(long millis,int nanos);
3.终止线程:
public void stop();
public void interrupt();
4.得到线程状态:
public boolean isAlive();
public boolean isInterrupted();
public static boolean interrupted();
5.join方法:
public void join() throws InterruptedException;
一、创建并运行线程:
线程在创建后并不是马上执行run方法中的代码,而是出于等待状态。线程在等待状态时,可以通过Thread类的方法来设置线程各种属性,线程优先级(setPriority),线程名字(setName),线程类型(setDaemon)等。
当调用start方法后,就会开始执行run()中的代码,此时线程进入运行状态,可以通过Thread类中的isAlive方法来判断线程是否处于运行状态。isAlive返回false时,线程可能处于等待状态或者停止状态,相反,返回true时线程正在运行。
如以下代码:
public class ThreadDemo extends Thread{
@Override
public void run() {
int n =0;
while(n<1000){
n++;
}
}
public static void main(String[] args) throws InterruptedException {
ThreadDemo thr1 = new ThreadDemo();
System.out.println("isAlive:"+thr1.isAlive());
thr1.start();
System.out.println("isAlive"+thr1.isAlive());
thr1.join();
System.out.println("thread1已经运行完毕!");
System.out.println("isAlive:"+thr1.isAlive());
}
}
结果为:
注意:在上面代码中用了join()方法,这个方法的作用是保证线程的run方法完成后程序才继续运行。
二、挂起和唤醒线程:
一旦线程开始执行run()方法后,就会一直到这个方法执行完成线程才会退出。但在这个线程执行的过程中,可以通过suspend()和sleep()这两个方法使线程暂时停止执行。使用suspend()挂起线程后,可以通过resume()唤醒线程。使用sleep()使线程休眠后,可以自己设定时间长短让线程处于就绪状态,等待系统调度。
虽然suspend()和resume()可以很方便使线程挂起和唤醒,可是可能造成某些事情发生,所以这个方法可能被删除,尽量不要使用这两个方法。
下面代码演示sleep()、suspend()和resume()三个方法的使用:
public class ThreadDemo extends Thread{
public static String dateToString(Date time){
SimpleDateFormat formatter;
formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String ctime = formatter.format(time);
return ctime;
}
public class SleepDemo extends Thread{
@Override
public void run() {
try {
sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
@Override
public void run() {
while(true){
System.out.println(new ThreadDemo().dateToString(new java.util.Date()));
}
}
public static void main(String[] args) throws InterruptedException {
ThreadDemo thr1 = new ThreadDemo();
SleepDemo sld1 = thr1.new SleepDemo();
sld1.start();
sld1.join();
thr1.start();
boolean flag = false;
while(true){
sleep(5000);
flag = !flag;
if(flag){
thr1.suspend();
}else{
thr1.resume();
}
}
}
}
总结:从表面上看,使用sleep()和suspend()所产生的效果类似,但sleep()方法并不等同于suspend()。因为一个线程中可以通过suspend()来挂起另外一个线程。sleep()只对当前正在执行的线程起作用。
三、终止线程的三种方法:
1.使用退出标志,使线程正常退出,也就是当run()完成后线程终止;
2.使用stop()强制终止线程;
3.使用interrupt()中断线程。
第一种:通过设一个boolean类型的标志来确定是否退出。
public class ThreadFlag extends Thread{
public volatile boolean exit = false;
@Override
public void run() {
while(!exit){
System.out.println(new ThreadDemo().dateToString(new Date()));
}
}
public static void main(String[] args) throws InterruptedException {
ThreadFlag tf = new ThreadFlag();
tf.start();
sleep(5000);
tf.exit = true;
tf.join();
System.out.println("线程退出!");
}
}
第二种:使用stop()终止线程。(不推荐使用)
第三种:使用interrupt()终止线程:
1.线程处于阻塞状态,如使用了sleep()方法,可以中断;
2.使用while(!isInterrupted()){...}来判断线程是否中断。
下面代码演示第一种情况使用interrupt():
public class ThreadIn extends Thread{
@Override
public void run() {
try {
sleep(50000);
} catch (InterruptedException e) {
System.out.println(e.getMessage());
}
}
public static void main(String[] args) throws Exception {
ThreadIn ti = new ThreadIn();
ti.start();
System.out.println("50秒内按任意键中断线程!");
System.in.read();
ti.interrupt();
ti.join();
System.out.println("线程退出!");
}
}
有两个方法可以判断线程是否通过interrupt()终止。一个是静态方法interrupted(),一个是非静态方法isInterrupted()。
区别:interrupted()用来判断当前线程是否被中断,而isInterrupted可以用来判断其他线程是否被中断。
以上就是线程的生命周期内容啦~