经过上次的介绍,对于线程的创建和启动已经有了基本认知,这篇文章在其基础上将对线程的状态和状态转换常用方法进行介绍。
1.线程状态
在Java中,线程状态主要分为以下几种状态
new状态:一个线程被new出来,但是没有调用start()方法使,这个线程处于新建状态。
runable状态:就绪状态。值得注意的是,一个线程被调用start()方法,并不会立即进入运行状态,而是在一个可运行状态,只有当该线程拿到cpu资源示,才能开始工作。
running状态:在拿到cpu时间片并处理run()方法中的业务逻辑的过程叫做run状态。
blocked状态:线程在执行过程中由于部分同步代码片段暂时无法拿到锁资源导致等待资源的状态。
waiting状态:无期限等待另一个线程执行特定操作的线程处于此状态。
timed_waiting状态:等待另一个线程执行操作达到指定等待时间的线程处于此状态。
terminated状态:终止状态,该线程全部工作完成,进入此状态。
我们通过图文的形式来描述线程间的状态转换:
2.线程状态转换的常用方法
start()方法:见作者博文:http://t.csdn.cn/sNy01
sleep()方法:调用该方法的线程会进入休眠状态,可通过参数控制线程休眠时间。
join()方法:在a线程执行过程中调用b.join(),a线程会进入阻塞状态,直到b线程执行结束。
wait()方法:调用该方法必须在sychronized修饰的代码中,会使当前线程释放锁资源,并且进入等待状态,等待被唤醒。
notify()方法:调用该方法会将等待该对象锁资源的其中一个线程业务唤醒,去争夺锁资源,而notifyAll()则是唤醒所有的线程去抢夺锁资源。
interrupted()方法:调用该方法会将在阻塞状态中的线程中断,需要注意的是并不是中断正在运行中的正常线程,而是针对处于阻塞状态中的线程。
3.join方法的使用
class Mthread extends Thread{
@Override
public void run() {
System.out.println("子线程开始执行");
System.out.println("子线程执行结束");
}
}
public class test2 {
public static void main(String[] args) {
System.out.println("主线程开始执行");
Thread t=new Mthread();
t.start();
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("主线程执行结束");
}
运行结果如下,可以看到主线程一直在子线程运行结束之后才继续执行。
4.interrupt()方法使用
interrupt()并不能中断终止正在正常运行的线程,只是中断线程的阻塞状态
class xThread extends Thread{
@Override
public void run() {
System.out.println("子线程开始执行");
for (int i=0;i<=10;i++){
System.out.println(i+"hello world");
}
}
}
public class test3 {
public static void main(String[] args) {
xThread xThread = new xThread();
xThread.start();
xThread.interrupt();
}
}
如代码所示,主线程在启动子线程之后试图使用interrupt()方法中断该线程的进行,但是由运行结果可以看出并没有达到想要的目的:
下面来看正确的使用方式
class xThread extends Thread{
@Override
public void run() {
int n=1;
bThread bThread = new bThread();
System.out.println("子线程开始执行");
bThread.start();
try {
bThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
bThread.interrupt();
}
}
class bThread extends Thread {
@Override
public void run() {
int n=1;
System.out.println("b线程开始执行");
while (!isInterrupted()){
n++;
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("B"+n+"helloword");
}
}
}
public class test3 {
public static void main(String[] args) throws InterruptedException {
xThread xThread = new xThread();
xThread.start();
Thread.sleep(1000);
xThread.interrupt();
xThread.join();
}
}
上述代码描述了在主线程中创建xthread线程,在xthread线程执行任务中需要启动bthread执行任务,bthread的join()方法使得xthraed进入了阻塞状态,此时在主线程中打断xthread的阻塞状态,抛出异常,程序结束。运行结果如下:
常用的两个方法就总结到这里,后续会介绍多线程中线程同步带来的问题以及处理方案。