1 线程状态
- 新生状态
用
new
关键字和Thread
类或其子类建立一个线程对象后,该线程对象就处于新生状态。处于新生状态的线程有自己的内存空间,通过调用start
方法进入就绪状态(runnable
)
- 就绪状态
处于就绪状态的线程已经具备了运行条件,但还没有分配到CPU,处于线程就绪队列,等待系统为其分配CPU。等待状态并不是执行状态,当系统选定一个等待执行的
Thread
对象后,它就会从等待执行状态进入执行状态,系统挑选的动作被称为“CPU调度”。一旦获得CPU,线程就进入运行状态并自动调用自己的run()
方法
- 运行状态
在运行状态的线程执行自己的
run()
方法中代码,直到调用其他方法而终止、或等待某资源而阻塞或完成任务而死亡。如果在给定的时间片内没有执行结束。就会被系统给换下来回到等待执行状态
- 阻塞状态
处于运行状态的线程在某些情况下,如执行了
sleep()
方法,或等待I/O设备等资源,将让出CPU并暂时停止自己的运行,进入阻塞状态。在阻塞状态的线程不能进入就绪队列,只有当引起阻塞的原因消除时,如睡眠时间已到,或等待的I/O设备空闲下来,线程便转入就绪状态,冲洗到就绪队列中排队等待,被系统选中后从原来停止的位置开始继续运
- 死亡状态
死亡状态是线程声明周期中的最后一个状态,线程死亡的原因有两个,一个是正常运行的线程完成了它的全部工作,另一个是线程被强制性地终止。如果通过执行
stop()
或destroy()
方法来终止一个线程**(不推荐)**,前者会产生异常,后者是强制重视,不会释放锁
2 停止线程
- 自然终止:线程体正常执行完毕后终止
- 外部干涉:
- 线程类中定义线程体使用的标识
- 线程体使用该标识
- 线程类中提供方法改变标识
- 外部条件调用该改变标识的方法即可
public class ThreadStopTest {
public static void main(String[] args) {
test t = new test();
new Thread(t).start();
for (int i = 0; i < 100; i++) {
// 当运行到25时,线程停止
if (i == 25) {
t.stopThread();
}
System.out.println("main..." + i);
}
}
}
class test implements Runnable {
// 线程体使用标识
private boolean flag = true;
// 线程体
@Override
public void run() {
int i = 0;
while (flag) {
System.out.println("run...." + i);
i++;
}
}
// 当flag为false时停止线程
public void stopThread() {
this.flag = false;
}
}
3 阻塞线程
join()
:合并线程
public class ThreadJoin {
public static void main(String[] args) {
test01 t = new test01();
Thread thread = new Thread(t);
thread.start();
for (int i = 0; i < 100; i++) {
try {
thread.join(); // 合并线程后,需要先运行test01线程后,再运行main线程,此时main线程被阻塞
System.out.println("main" + i);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
class test01 implements Runnable {
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println("test" + i);
}
}
}
yield()
:暂停当前正在执行的线程对象,并执行其他线程(静态方法)
public class ThreadYield {
public static void main(String[] args) {
testYield test = new testYield();
Thread thread = new Thread(test);
thread.start();
for (int i = 0; i < 100; i++) {
// Thread.yield(); // 写在哪个线程中就暂停哪个线程,此时main线程被阻塞
System.out.println("main" + i);
}
}
}
class testYield implements Runnable {
@Override
public void run() {
for (int i = 0; i < 100; i++) {
Thread.yield(); // 此时testYield线程被阻塞
System.out.println("testYield" + i);
}
}
}
sleep()
:线程休眠- 与时间相关:倒计时
- 模拟网络延迟
/**
* 模拟倒计时
*
* @author Administrator
*
*/
public class ThreadSleep {
public static void main(String[] args) {
// 获取十秒后的时间
Date endTime = new Date(System.currentTimeMillis() + 10 * 1000);
Date nowTime = null;
SimpleDateFormat s = new SimpleDateFormat("HH:mm:ss");
while (true) {
// 获取当前时间
nowTime = new Date(System.currentTimeMillis());
if (nowTime.compareTo(endTime) < 0) {
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(s.format(nowTime));
} else {
break;
}
}
}
}