前言
本篇内容主要分析多线程中的核心类Thread
的使用,从源码级别入口。学习线程的初始化以及启动中的一些流程。
课程目标
1.线程Thread的初始化以及启动方法的核心流程 2.后台线程Dameon 3.join()的应用场景及原理 4.interrupt()的应用 5.wait()与notify()
1. Thread
类的源码解析
1.1.初始化流程
入口方法:
init(g, target, name, stackSize, null, true);
1.把当前线程设置为新线程的父线程 2.每个线程都会有一个线程组(ThreadGroup),若没有指定,则线程组就是父线程的线程组 3.当前线程的daemon默认为父线程的daemon状态 4.线程优先级默认是父线程的优先级 5.线程id是全局递增,从1开始。
1.2. 启动流程
入口方法
public synchronized void start()
public synchronized void start() {
if (threadStatus != 0)
throw new IllegalThreadStateException();
group.add(this);
boolean started = false;
try {
start0();
started = true;
} finally {
try {
if (!started) {
group.threadStartFailed(this);
}
} catch (Throwable ignore) {
}
}
}
1. threadStatus
默认为0,线程一旦执行过之后,就会变为非0的状态,此时现在不能再次被start();2.你启动线程之后,这个线程就会加入之前处理好的那个线程组中 3.启动一个线程实际上走的是native方法,start0(),会实际的启动一个线程 4.一个线程启动之后就会执行run()方法
2.Daemon(后台线程)
又称为守护线程,当工作线程都停止的话,那么
Daemon
会跟着jvm进程一起退出;
即可设置为后台线程
thread.setDaemon(true);
3.join()的应用场景及原理
如果在main线程中调用其他线程,则main线程和其他线程会并发执行。 如果在main线程中调用了另一个线程的join,那么main线程就会阻塞住,等待其他线程执行完毕。 如下代码,我们实现一个注册功能,必须要先完成注册再进行心跳,所以在主线程中我们就先阻塞主线程等待完成之后再进行心跳
如下图代码,如果没有执行registerWorker.join();
,那么就会出现注册完成之前,调用heartbeatWorker.start();
从而出现注册完成之前,先发送心跳的情况。
public void start() {
try {
// 一旦启动了这个组件之后,他就负责在服务上干两个事情
// 第一个事情,就是开启一个线程向register-server去发送请求,注册这个服务
// 第二个事情,就是在注册成功之后,就会开启另外一个线程去发送心跳
// 我们来简化一下这个模型
// 我们在register-client这块就开启一个线程
// 这个线程刚启动的时候,第一个事情就是完成注册
// 如果注册完成了之后,他就会进入一个while true死循环
// 每隔30秒就发送一个请求去进行心跳
RegisterWorker registerWorker = new RegisterWorker();
registerWorker.start();
registerWorker.join();
heartbeatWorker.start();
} catch (Exception e) {
e.printStackTrace();
}
}
4.interrupt()的应用
在一个线程中调用另一个线程的interrupt()方法,即会向那个线程发出信号——线程中断状态已被设置。至于那个线程何去何从,由具体的代码实现决定。
public class InterruptDemo {
public static void main(String[] args) throws InterruptedException {
MyThread t1 = new MyThread();
t1.start();
Thread.sleep(1000);
t1.setShouldRun(false);
t1.interrupt();
System.out.println(">>>>>>>>>>>>>>>>>>>>>"+t1.isInterrupted());
}
private static class MyThread extends Thread{
private boolean shouldRun = true;
@Override
public void run() {
while (shouldRun){
try {
System.out.println(Thread.currentThread().getName()+"正在工作......");
Thread.sleep(30*1000);
}catch (Exception e){
e.printStackTrace();
}
}
}
public void setShouldRun(boolean shouldRun){
this.shouldRun = shouldRun;
}
}
}
主要应用与中断其他线程的休眠,和sleep结合,用于标志位的处理。
5.wait()与notify()
文章转载自阿亮的日志,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




