线程状态
NEW 尚未启动的线程(新生)
RUNNABLE 在Java虚拟机中执行的线程(运行)
BLOCKED 被阻塞等待监视器锁定的线程(阻塞)
WAITING 正在等待另一个线程执行特定动作的线程(阻塞)
TIMED_WAITING 正在等待另一个线程执行动作达到指定等待时间的线程(阻塞)
TERMINATED 已退出的线程(死亡)
观测线程状态,一个线程可在给定时间点处于一个状态,这些状态不反映任何操作系统线程状态的虚拟机状态
//观测线程状态
public class TestState {
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(()-> {
for (int i = 0; i < 5; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
//观察状态
Thread.State state = thread.getState();
System.out.println(state); //NEW
//观察启动
thread.start(); //启动线程
state = thread.getState();
System.out.println(state); //RUN
while(state != Thread.State.TERMINATED){ //线程不终止,则一直输出状态
Thread.sleep(100);
state = thread.getState(); //更新线程状态
System.out.println(state);
}
//死亡后的线程不能再次启动
//thread.start();
}
}
1.线程停止
//建议线程正常停止 设置标志位 不使用stop、destory等过时或者JDK不建议使用的方法
public class TestStop 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) {
TestStop testStop = new TestStop();
new Thread(testStop).start();
for (int i = 0; i < 1000; i++) {
System.out.println("main" + i);
if(i==900){
//调用stop方法切换标志位,停止线程
testStop.stop();
System.out.println("线程即将停止");
}
}
}
}
不推荐使用方法stop()、destroy()
推荐线程自己停止
使用标志位终止变量,flag=false,终止线程
2.线程休眠
模拟买票
//模拟网络延时 方法问题发生性
public class TestSleep implements Runnable{
//票数
private int ticketNums = 10;
@Override
public void run() {
while(true){
if(ticketNums <= 0){
break;
}
//模拟延时
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "-->拿到了" + ticketNums-- + "票");
}
}
public static void main(String[] args) {
TestSleep ticket = new TestSleep();
new Thread(ticket, "学生").start();
new Thread(ticket, "公务员").start();
new Thread(ticket, "老师").start();
}
}
倒计时
import java.text.SimpleDateFormat;
import java.util.Date;
//模拟倒计时
public class TestSleep02 {
public static void main(String[] args) throws InterruptedException {
Date startTime = new Date(System.currentTimeMillis()); //获取系统当前时间
while(true){
Thread.sleep(1000);
System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(startTime));
startTime = new Date(System.currentTimeMillis()); //更新当前时间
}
}
public static void turnDown() throws InterruptedException{
int num = 10;
while(true){
Thread.sleep(1000);
System.out.println(num--);
if(num<=0){
Thread.sleep(1000);
System.out.println("发射");
break;
}
}
}
}
sleep指定当前线程阻塞毫秒数
存在异常InterruptedException
达到后线程进入就绪状态
每个对象都有一个锁,sleep不会释放锁
3.线程礼让
public class TestYield {
public static void main(String[] args) {
MyYield myYield = new MyYield();
new Thread(myYield, "1").start();
new Thread(myYield, "2").start();
}
}
class MyYield implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "线程开始执行");
Thread.yield(); //礼让 不一定成功
System.out.println(Thread.currentThread().getName() + "线程停止执行");
}
}
让当前正在执行的线程暂停,但不阻塞
将线程从运行状态转为就绪状态
CPU重新调度,礼让不一定成功
4.线程强制执行
//线程强制执行
public class TestJoin implements Runnable {
@Override
public void run() {
for (int i = 0; i < 1000; i++) {
System.out.println("插队线程" + i);
}
}
public static void main(String[] args) throws InterruptedException {
TestJoin testJoin = new TestJoin();
Thread thread = new Thread(testJoin);
//启动线程
thread.start();
//主线程
for (int i = 0; i < 1000; i++) {
if (i == 200) {
thread.join(); //强制执行 插队
}
System.out.println("main" + i);
}
}
}
Join强制执行线程,待此线程执行完成后,再执行其他线程,其他线程阻塞