1、线程有5种状态:新建(new Thread)、就绪(runnable),运行(running)、阻塞(blocked)、结束(dead)
主要方法:
setPriority:更改优先级
sleep(休眠):休眠多少毫秒;每个对象都有一把锁,sleep不会释放锁
join(加入):插队,当有新的线程加入时,主线程会进入等待状态,一直到调用join()方法的线程执行结束为止。
yield(礼让):线程A抢到CPU了,线程B在外面等待,这是线程A调用yield()方法,就会退出来和线程B一起再抢一次
注:yield()方法只是提出申请释放CPU资源,至于能否成功释放由JVM决定。由于这个特性,一般编程中用不到此方法,但在很多并发工具包中,yield()方法被使用,如AQS、ConcurrentHashMap、FutureTask等。
isAlive:测试线程是否处于活动状态
yield()方法和sleep()方法有什么区别
yield()方法调用后线程处于RUNNABLE(就绪)状态,而sleep()方法调用后线程处于TIME_WAITING(等待)状态,所以yield()方法调用后线程只是暂时的将调度权让给别人,但立刻可以回到竞争线程锁的状态;而sleep()方法调用后线程处于阻塞状态。
sleep()和wait()方法有什么区别:
sleep()睡眠时,保持对象锁,仍然占有该锁;
而wait()睡眠时,释放对象锁。
但是wait()和sleep()都可以通过interrupt()方法打断线程的暂停状态,从而使线程立刻抛出InterruptedException(但不建议使用该方法)。
sleep()的小应用:每秒打印一次时间
public class TestSleep {
public static void main(String[] args) throws InterruptedException {
//获取当前时间:毫秒
Date start = new Date(System.currentTimeMillis());
while(true){
//睡眠一秒钟
Thread.sleep(1000);
//转成标准格式
System.out.println(new SimpleDateFormat("HH:mm:ss").format(start));
//刷新当前时间
start = new Date(System.currentTimeMillis());
}
}
输出结果:
17:13:59
17:14:00
17:14:01
17:14:02
17:14:03
17:14:04
yield方法使用:
public class TestYield {
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() + "结束执行");
}
}
执行结果:
线程a开始执行
线程b开始执行
线程b结束执行
线程a结束执行
join()方法小测试:大佬插队
package com.bes.mybatis_plus.TestState;
public class TestJoin implements Runnable{
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
for(int i = 0; i < 3; i ++ ){
System.out.println("线程VIP来了" + 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 < 5; i++) {
//主线程跑两次之后,上面线程强势插队,完成之后才轮到main线程继续
if(i == 2){
thread.join();// 插队
}
System.out.println("main" + i);
}
}
}
main0
main1
线程VIP来了0
线程VIP来了1
线程VIP来了2
main2
main3
main4
jdk里线程的六种状态:
NEW (新建)
线程尚未启动的线程状态。
RUNNABLE (就绪,可运行的)
可运行线程的线程状态。
BLOCKED (阻塞)
一个线程的线程状态阻塞等待监视器锁定。
TIMED_WAITING (计时等待)
具有指定等待时间的等待线程的线程状态。
WAITING (等待)
等待线程的线程状态
TERMINATED (结束)
终止线程的线程状态。
看代码:
package com.bes.mybatis_plus.TestState;
//观测线程的不同状态
public class TestState {
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(()->{
for (int i = 0; i < 3; i++) { //休眠三秒
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
//线程执行完成之后,打印完成
System.out.println("线程执行完毕");
});
//观察线程的状态,此时,没有start启动,应该是new新建状态
Thread.State state = thread.getState();
System.out.println(state); //NEW
//观察启动之后
thread.start();
//再次获得线程状态
state = thread.getState();
System.out.println(state); //RUNNABLE
while(state != Thread.State.TERMINATED){ //线程不是终止状态
Thread.sleep(300);
//再次获得线程状态
state = thread.getState();
System.out.println(state); //输出状态
}
}
}
执行结果:
NEW
RUNNABLE
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
线程执行完毕
TERMINATED
注:当线程TERMINATED(结束)之后,是不可以再启动的