Java线程是如何启动的?
简单来说:
- Java创建线程和启动
- 调用本地方法start0()
- JVM中JVM_StartThread的创建和启动
- JVM中设置线程状态,等待被唤醒
- JVM根据不同的OS启动线程并且唤醒
- 最后回调run()方法启动Java线程
Thread的状态转换
Java.lang.Thread.State枚举类中存在6个状态:
new runnable blocked waiting timed_waiting terminated
new: "new Thread()"操作之后,线程的状态
runnable:thread调用start()方法之后,但是还没有执行完成或被打断的状态。
blocked :在有锁竞争的情况下,没有抢到锁之后进入的阻塞状态。
waiting :没有设置时间的等待,需要另一个线程操作唤醒的状态
timed_waiting :设置了时间的等待
terminated:线程正常调用完成
状态展示代码
public class TestThreadState {
public static void main(String[] args) throws InterruptedException {
// test_new();
// test_runnable();
// test_blocked();
// test_waiting();
// test_timed_waiting();
terminated();
}
/**
* @Description: TERMINATED正常执行完成之后
* @Author: zhy
* @Date: 2021/7/15 15:51
* @Param: []
* @return: void
*/
private static void terminated() {
Thread thread = new Thread(() -> {
});
thread.start();
System.out.println(thread.getState());
System.out.println(thread.getState());
System.out.println(thread.getState());
}
/**
* @Description: sleep设置时间以及有些代码设置时间等待的
* @Author: zhy
* @Date: 2021/7/15 15:52
* @Param: []
* @return: void
*/
private static void test_timed_waiting() throws InterruptedException {
Object obj = new Object();
Thread thread = new Thread(() -> {
synchronized (obj) {
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
thread.start();
while (true) {
Thread.sleep(1000);
System.out.println(thread.getState());
}
}
/**
* @Description: 没有设置时间的等待,需要另一个线程操作唤醒的状态
* @Author: zhy
* @Date: 2021/7/15 15:53
* @Param: []
* @return: void
*/
private static void test_waiting() throws InterruptedException {
Object obj = new Object();
Thread thread = new Thread(() -> {
synchronized (obj) {
try {
obj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
thread.start();
while (true) {
Thread.sleep(1000);
System.out.println(thread.getState());
}
}
/**
* @Description: 竞争锁时,阻塞的线程状态
* @Author: zhy
* @Date: 2021/7/15 15:53
* @Param: []
* @return: void
*/
private static void test_blocked() throws InterruptedException {
Object obj = new Object();
new Thread(()->{
synchronized (obj) {
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
Thread thread = new Thread(() -> {
synchronized (obj) {
try {
obj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
thread.start();
while (true) {
Thread.sleep(1000);
System.out.println(thread.getState());
}
}
/**
* @Description: 启动的线程
* @Author: zhy
* @Date: 2021/7/15 15:54
* @Param: []
* @return: void
*/
private static void test_runnable() {
Thread thread = new Thread(() -> {
});
thread.start();
System.out.println(thread.getState());
}
/**
* @Description: new Thread()之后的存在的状态
* @Author: zhy
* @Date: 2021/7/15 16:02
* @Param: []
* @return: void
*/
static void test_new() {
Thread thread = new Thread(() -> {
});
System.out.println(thread.getState());
}
}
线程状态之间进行切换
Thread的使用
start()
启动线程
yeild()
让出一下CPU,然后立即再去争取CPU。可能阻塞,也可能再次被CPU的执行。
wait()/notify()/notifyall()
这个一般是一个组合的使用。wait是当前线程进行等待(waiting),notify则是进行唤醒一个线程,notifyall是唤醒全部的线程。
join()
join相当于给线程插了一个队。join是一个sync方法,里边调用了wait(),让其他线程进行了等待,当调动join的线程执行完毕之后,在JVM中调用了lock.notify_all(),来唤醒其他线程。