一.线程的五大状态:创建状态、就绪状态、运行状态、阻塞状态、死亡状态
1**.创建状态**(新生状态):new 线程对象Thread t = new Thread();线程对象一旦创建,就进入了新生状态。
2.就绪状态:new出来以后,当调用start()方法,线程就会立即进入就绪状态,但不意味着立即调度执行。
3.运行状态:处于就绪状态的线程,经过CPU调度就会进入运行状态,线程才会真正执行线程体的代码块。
4**.阻塞状态**:当调用sleep、wait或同步锁定时,线程进入阻塞状态,就是代码块不往下执行,阻塞事件解除后,重新进入就绪状态,等待CPU调度执行。
5.死亡状态:线程中断或结束,一旦进入死亡状态,就不能再次启动。
二.线程的状态变化:
1.线程停止
不推荐使用JDK提供的stop()、destroy()方法(已废弃),推荐线程自己停下来:建议使用一个标志位进行终止变量,当flag=false时,则终止线程运行。
public class ThreadStop implements Runnable{
//1.设置一个标志位
private boolean flag = true;
@Override
public void run() {
int i = 0;
while (flag){
System.out.println("Thread is running..." + i++);
}
}
//2.设置一个公开的方法来停止线程,切换标志位
public void stop(){
this.flag = false;
}
public static void main(String[] args) {
ThreadStop threadStop = new ThreadStop();
new Thread(threadStop).start();
for (int i = 0; i < 1000; i++) {
System.out.println("main线程" + i);
if (i == 900){
//调用自己写的stop()方法来停止线程
threadStop.stop();
System.out.println("线程该停止了");
}
}
}
}
运行结果:
2.线程休眠sleep()方法
sleep(时间)指定当前线程阻塞的毫秒数
sleep存在异常InterruptedException,需要抛异常
sleep时间达到后线程进入就绪状态
sleep可以模拟网络延时、倒计时等功能
每一个对象都有一把锁,sleep不会释放锁
sleep实现倒计时功能:
//倒计时
public class ThreadSleep {
public static void main(String[] args) {
try {
tenDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void tenDown() throws InterruptedException {
int num = 10;
while (true){
Thread.sleep(1000);
System.out.println(num--);
if (num <= 0){
break;
}
}
}
}
sleep实现获取当前时间的功能:
import java.text.SimpleDateFormat;
import java.util.Date;
//获取当前体统时间
public class ThreadSleep2 {
public static void main(String[] args) {
Date startTime = new Date(System.currentTimeMillis()); //获取当前系统时间
while (true){
try {
Thread.sleep(1000);
//将当前时间打印出来
System.out.println(new SimpleDateFormat("HH:mm:ss").format(startTime));
startTime = new Date(System.currentTimeMillis()); //更新当前时间
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
3.线程礼让yield()方法
线程礼让:让当前正在执行的线程停止,但并不是阻塞,将线程状态从运行状态转为就绪状态,让CPU重新调度,线程重新竞争;礼让不一定成功,看CPU心情
//线程礼让
public class ThreadYield {
public static void main(String[] args) {
MyYield myYield = new MyYield();
new Thread(myYield, "a").start();
new Thread(myYield, "b").start();
}
}
class MyYield implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "线程开始执行");
Thread.yield(); //礼让
System.out.println(Thread.currentThread().getName() + "线程停止执行");
}
}
结果:
礼让成功:
礼让失败:
4.线程强制执行join()
可以想象成插队,待此线程执行完毕后,再执行其他线程,其他线程阻塞
//测试join 方法
public class ThreadJoin implements Runnable{
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println("我要插队!" + i);
}
}
public static void main(String[] args) throws InterruptedException {
for (int i = 0; i < 1000; i++) {
if (i == 200){
ThreadJoin threadJoin = new ThreadJoin();
Thread thread = new Thread(threadJoin);
thread.start();
thread.join();
}
System.out.println("main" + i);
}
}
}