对于时间片这个概念,应该大家都不会太陌生,没错,正如前文所讲,正是要挖掘'计算机空闲的时间片(分时管理忘记的话,自己充下电吧),谈最基本的线程得还是敲出第一个'HelloWord'的印象方法用到的主线程也就是main。
目录
1、进程、线程与程序的奇妙关系
众所周知,主线程的方法跑完之后,应用程序就会结束,如果在方法内在创建线程(算得上其他线程),则时间片的机制就会出现,会在新线程与主线程之间切换,暂且称为‘左右横跳’,一直等到所有程序完成执行,整个程序才会被JVM给结束掉。
2、线程的一生(生命周期)
①出生(新建)
当一个线程被声明创建时,它就出生了,自然而然,有属于它的生活环境和出生证明(配给相应的内存空间及必要资源)
②干活(运行)
为了生存,它必须要干活,但是干活需要健康证明,你要去跟工头(JVM)说你要干活(调用start方法),工头才会给你安排工作机会(该线程才进入等待队列等候时间片切换)
但是具体的工种内容你是可以选择的,做啥工作(一般在线程方法中重写run方法来执行你需要执行的内容)
③工作历程(中断)
1、JVM大佬将原本属于本线程的翻倍加班工资机会,安排给了一个有门道的线程,领导安排,只能让出机会(CPU资源被调配,本线程让出CPU的使用权并置为中断状态)
2、上班期间(使用CPU资源期间),突然很困,想休息一会儿(执行sleep方法),然后被老板看到,只能先让出工作机会(让出CPU使用权,同时线程置为中断状态),等睡醒后(sleep等待时间结束后)继续排队等候工头工作安排(重新加入CPU资源等候队列,以使线程从中断中恢复并继续运行)
3、工作期间(使用CPU资源期间),突然不想起床,只想别人主动叫才去排队干活,又可以偷懒了。(执行wait方法,使得线程进入等待状态,需要其他线程调用notify等方法唤醒才能继续排队等候CPU资源并从终端出继续运行)
4、干活期间(使用CPU资源期间),突然被动物抓伤,只能暂时停下工作去医院看伤(进入阻塞状态【本状态下不能进入CPU排队状态】),等伤好之后才能继续回去等通知继续回到岗位继续干活(等阻塞结束后才可以进入队列中等待CPU调度,从中断处继续运行)
④凉凉(死亡)
当线程不存在继续工作的能力的时候,就会被饿死凉凉,尸体重新回哺大地(释放实体及分配给它的内存)
1、完成了所有的工作后,公司就不需要它来分钱了,踢出门饿死(执行完run中所有语句)
2、被强制辞退,饿死(强制run方法结束)
3、线程贵族体系(线程的优先级)
人有三六九之分,线程也难逃命运,调度器大佬就是来管理贵族体系的执行者了
一般分为10个级别,部分特定虚拟机只能识别3个,高(10)中(5,默认)低(1)
并不是说线程优先级高就会等优先级高的处理完,低优先级的才轮到分配时间片,这点虽然书上是这样说的,但实际上并不是这 样,要谨记,实践才是硬道理
4、线程的常用方法
①start()
进入CPU资源等待队列,脱离创建线程独立运行,拥有自己的生命周期
②run()
一般不直接运行调用,由线程对象被调用start()方法后被系统调用。直接运行时,相当于触发普通方法,归属于启用它的线程
Tips: 如果线程没有运行完run()内的方法,继续调用start(),则会发生 ILLegalThreadStateException()异常
③sleep(int millsecond)
用于让出CPU资源而使自己休眠,如需要调用正在休眠的线程(常调用interrup()方法),需要在try-catch中处理,因为打断休眠的时,会造成InterruptedException()
④isAlive()
仅在线程调用start()方法后和run方法执行完毕前才会返回true
最后注意一下:
一个已经运行的线程,没有进入死亡状态(也就是run()没有结束前)时,再给线程分配实体,先前分配的实体就会成为‘’垃圾‘’(因为线程只能引用最后分配的实体),并且不会不被垃圾收集回收掉。
public class TestThread extends Thread {
int time = 0;
SimpleDateFormat m = new SimpleDateFormat("hh:mm:ss");
Date date;
public void run() {
while (true) {
date = new Date();
System.out.println(this.currentThread().getName() + "|" + date);
time++;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
if (time == 3) {
Thread thread = Thread.currentThread();
thread = new Thread(this);
thread.start();
}
}
}
public static void main(String[] args) throws InterruptedException {
TestThread mt = new TestThread();
mt.start();
}
}
执行情况:
Connected to the target VM, address: '127.0.0.1:50949', transport: 'socket'
Thread-0|Sun May 12 11:01:59 GMT+08:00 2019
Thread-0|Sun May 12 11:02:00 GMT+08:00 2019
Thread-0|Sun May 12 11:02:01 GMT+08:00 2019
Thread-0|Sun May 12 11:02:02 GMT+08:00 2019
Thread-1|Sun May 12 11:02:02 GMT+08:00 2019
Thread-0|Sun May 12 11:02:03 GMT+08:00 2019
Thread-1|Sun May 12 11:02:03 GMT+08:00 2019
Thread-0|Sun May 12 11:02:04 GMT+08:00 2019
Thread-1|Sun May 12 11:02:04 GMT+08:00 2019
。。。。
旧实体会一直运行