【JavaEE多线程】理解和管理线程生命周期

Thread t3 = new Thread(“这是我的名字”);
Thread t4 = new Thread(new MyRunnable(), “这是我的名字”);```


#### Thread类的常见属性




| 属性 | 获取方法 |
| --- | --- |
| ID | getId() |
| 名称 | getName() |
| 状态 | getState() |
| 优先级 | getPriority() |
| 是否后台线程 | isDaemon() |
| 是否存活 | isAlive() |
| 是否被中断 | isInterrupted() |


1. ID(getId):线程的身份表示(在JVM这里给线程设定的身份标识),一个线程可以有多个身份标识
2. 名称(getName):各种调试工具用到
3. 状态(getState):Java中的线程状态和操作系统中有一定差异
4. 优先级(getPriority):设置/获取线程优先级作用不是很大,线程的调度主要还是系统内核来负责的,系统调度的速度实在太快
5. 是否后台线程(isDaemon)


	* 后台线程/守护线程:不太影响进程结束
	* 前台线程:会影响进程结束,如果前台线程没执行完,进程是不会结束的
	* 一个进程中所有的前台线程都执行完,退出了,此时即使存在后台线程仍然没执行完也会随着进程一起退出
	* 影响进程退出的就是前台,不影响的就是后台
	* 创建的线程默认是前台线程,通过setDaemon显式的设置成后台
6. 是否存活(isAlive):Thread对象,对应的线程(系统内核中)是否存活。


	* Thread对象的生命周期,并不是和系统中的线程完全一致的
7. 是否被中断(isInterrupted):看下面


#### 启动一个线程-start()


1. start方法,在系统中真正创建出线程
	1. 创建出PCB
	2. 把PCB加入到对应链表
2. 操作系统内核=内核+配套的程序
3. 内核:一个系统最核心的功能
	1. 对下,管理好各种硬件设备
	2. 对上,给各种程序提供稳定的运行环境
4. start方法本身执行成功是一瞬间的,只是告诉系统你要创建一个线程,调用完start后,代码就会立即继续执行start后续的逻辑


#### 终止一个线程


1. 一个线程的run方法执行完毕,就算终止了
2. 此处的终止线程,就是想办法让run方法能够尽快执行完毕
3. 方法:


	1. 程序员手动设定标志位,通过这个来让run尽快结束

private static class MyRunnable implements Runnable {
public volatile boolean isQuit = false;

@Override
public void run() {
    while (!isQuit) {
        System.out.println(Thread.currentThread().getName()
                + ": 别管我,我忙着转账呢!");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    System.out.println(Thread.currentThread().getName()
            + ": 啊!险些误了大事");
}

}

public static void main(String[] args) throws InterruptedException {
MyRunnable target = new MyRunnable();
Thread thread = new Thread(target, “李四”);
System.out.println(Thread.currentThread().getName()
+ “: 让李四开始转账。”);
thread.start();
Thread.sleep(10 * 1000);
System.out.println(Thread.currentThread().getName()
+ “: 老板来电话了,得赶紧通知李四对方是个骗子!”);
target.isQuit = true;
}


	2. 直接Thread类,给我们提供好了现成的标志位,不用手动设置标志位

private static class MyRunnable implements Runnable {
@Override
public void run() {
// 两种方法均可以
while (!Thread.interrupted()) {
//while (!Thread.currentThread().isInterrupted()) {
System.out.println(Thread.currentThread().getName()
+ “: 别管我,我忙着转账呢!”);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println(Thread.currentThread().getName()
+ “: 有内鬼,终止交易!”);
// 注意此处的 break
break;
}
}
System.out.println(Thread.currentThread().getName()
+ “: 啊!险些误了大事”);
}
}

public static void main(String[] args) throws InterruptedException {
MyRunnable target = new MyRunnable();
Thread thread = new Thread(target, “李四”);
System.out.println(Thread.currentThread().getName()
+ “: 让李四开始转账。”);
thread.start();
Thread.sleep(10 * 1000);
System.out.println(Thread.currentThread().getName()
+ “: 老板来电话了,得赶紧通知李四对方是个骗子!”);
thread.interrupt();
}

4. 当sleep被唤醒以后,程序员可以有以下几种操作方式:


	1. 立即停止循环,立即结束线程(直接break)
	2. 继续做点别的事情,过一会儿再结束线程(catch中执行别的逻辑,执行完再break)
	3. 忽略终止的请求,继续循环(不写break)
5. thread 收到通知的方式有两种:


	1. 如果线程因为调用 wait/join/sleep 等方法而阻塞挂起,则以 InterruptedException 异常的形式通知,**清除中断标志**
		* 当出现 InterruptedException 的时候, 要不要结束线程取决于 catch 中代码的写法. 可以选择忽略这个异常, 也可以跳出循环结束线程
	2. 否则,只是内部的一个中断标志被设置,thread 可以通过
		* Thread.interrupted() 判断当前线程的中断标志被设置,**清除中断标志**
		* Thread.currentThread().isInterrupted() 判断指定线程的中断标志被设置,**不清除中断标志**


#### 等待一个线程-join()


1. 多个线程是并发执行的。具体的执行过程都是由操作系统负责调度的。操作系统的调度线程的过程,是“随机”的。无法确定线程执行的先后顺序
2. 等待线程,就是一种规划 **线程结束** 顺序的手段
3. 注意:join()方法也会抛出Interrupted异常
4. **谁调用join方法,谁就强占cpu资源,直至执行结束**
5. A B两个线程,希望B先结束A后结束,此时就可以让A线程中调用B.join()的方法。此时,B线程还没执行完,A线程就会进入"阻塞"状态。就相当于给B留下了执行的时间。B执行完毕之后,A再从阻塞状态中恢复回来,并且继续往后执行。如果A执行到B.join()的时候,B已经执行完了,A就不必阻塞了,直接往下执行就可以了
6. 阻塞:让代码暂时不继续执行了(该线程暂时不去CPU上参与调度)
7. sleep也能让线程阻塞,阻塞是有时间限制的
8. join的阻塞,则是“死等”“不见不散”
9. **sleep、join、wait…产生阻塞之后,都是可能被interrupt方法唤醒的**,这几个方法都会在被唤醒之后自动清除标志位(和sleep类似),这些方法都会抛出Interrupted异常


#### 线程的状态


* 先谈谈进程里PCB里的状态字段:**就绪**和**阻塞**状态(这些是系统设定的状态,Java又把这些细分了)
* 以下则是**线程的状态:**


1. NEW\*\*(开始前)\*\*: 安排了工作, 还未开始行动 (Thread对象创建好了,但还没有调用start()方法)
2. RUNNABLE\*\*(就绪状态)**: 可工作的. 又可以分成**正在工作中**和**即将开始工作\*\*


	1. 线程正在CPU上运行
	2. 线程正在排队,随时可以去CPU运行
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值