一、线程的五大状态
1、Thread t = new Thread() 线程对象一旦创建就进入到 了创建状态。
2、当调用start()方法,线程立即 进入就绪状态,但不意味着 立即调度执行。
3、就绪状态通过cpu调度进入运行状态,线程才真正 执行线程体的代码块。
4、当调用sleep,wait 或同步 锁定时,线程进入阻塞状态, 就是代码不往下执行,阻塞 事件解除后,重新进入就绪 状态,等待cpu调度执行。
5、线程中断或者结束,一旦进 入死亡状态,就不能再次启动。
二、线程方法
1、线程停止
//建议线程正常停止---------利用次数,不要死循环
//建议使用标志位-------------设置一个标志位
//不要使用stop或者destory等过时的方法
public class Testa implements Runnable{
//设置一个标志位
private boolean flag=true;
@Override
public void run() {
int i=0;
while (flag){
System.out.println("正在运行"+i++);
}
}
public void stop(){
this.flag=false;
}
public static void main(String[] args) {
Testa testa = new Testa();
new Thread(testa).start();
for (int i = 0; i < 1000; i++) {
System.out.println("main"+i);
if(i==900){
testa.stop();
System.out.println("子线程停止了");
}
}
}
}
2、线程休眠
- sleep (时间) 指定当前线程阻塞的毫秒数;
- sleep存在异常InterruptedException;(要try{}catch{})
- sleep时间达到后线程进入就绪状态;
- sleep可以模拟网络延时,倒计时等。
- 每一个对象都有一个锁,sleep不会释放锁;
-
public class TestSleep { public static void main(String[] args) throws InterruptedException { //模拟倒计时 TestSleep.tendown(); //打印当前系统时间 Date date = new Date(System.currentTimeMillis()); while (true){ Thread.sleep(1000); System.out.println(new SimpleDateFormat("HH:mm:ss").format(date)); date = new Date(System.currentTimeMillis()); } } //模拟倒计时 public static void tendown() throws InterruptedException { int num = 10; while (true){ System.out.println(num--); Thread.sleep(1000); if(num<=0) break; } } }
3、线程礼让
- 礼让线程,让当前正在执行的线程暂停,但不阻塞
- 将线程从运行状态转为就绪状态
- 让cpu重新调度,礼让不一定成功!看CPU心情
-
public class TestYield { static class MyYelid implements Runnable{ @Override public void run() { System.out.println(Thread.currentThread().getName()+"线程开始执行"); Thread.yield(); System.out.println(Thread.currentThread().getName()+"线程停止"); } } public static void main(String[] args) { MyYelid myYelid = new MyYelid(); new Thread(myYelid,"A").start(); new Thread(myYelid,"B").start(); } }
4、join方法
-
Join 合并线程,待此线程执行完成后,再执行其他线程,其他线程阻塞
-
public class TestJoin implements Runnable{ @Override public void run() { for (int i = 0; i < 1000; i++) { System.out.println("vip线程来了"+i); } } public static void main(String[] args) { Runnable testJoin = new TestJoin(); Thread thread = new Thread(testJoin); thread.start(); for (int i = 0; i < 1000; i++) { System.out.println("主线程运行"+i); if(i==200) { try { thread.join(); //vip进程插队 } catch (InterruptedException e) { e.printStackTrace(); } } } } }
三、线程状态观测
Thread.State
//观测线程状态
public class TestState {
public static void main(String[] args) {
Thread thread = new Thread(()->{
for (int i = 0; i < 5; i++) {
try {
Thread.sleep(1000);
System.out.println(i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("///");
});
Thread.State state = thread.getState();
System.out.println(state); //NEW
thread.start();
state = thread.getState();
System.out.println(state); //EUNABLE
while (state!=Thread.State.TERMINATED) {
try {
thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
state = thread.getState();
System.out.println(state);
}
//thread.start();死亡的线程不能二次启动
}
}