b站学习视频以及笔记-尚硅谷_Java零基础教程
Thread类中的常用的方法以及生命周期:
1. Thread类中的常用的方法
- start():启动当前线程;调用当前线程的run()
- run(): 通常需要重写Thread类中的此方法,将创建的线程要执行的操作声明在此方法中
- currentThread():静态方法,返回执行当前代码的线程
- getName():获取当前线程的名字
- setName():设置当前线程的名字
- yield():释放当前cpu的执行权
- join():在线程a中调用线程b的join(),此时线程a就进入阻塞状态,直到线程b完全执行完以后,线程a才结束阻塞状态。
- stop():已过时。当执行此方法时,强制结束当前线程。
- sleep(long millitime):让当前线程“睡眠”指定的millitime毫秒。在指定的millitime毫秒时间内,当前线程是阻塞状态。
- isAlive():判断当前线程是否存活
2. 线程的优先级:
-
线程的优先级等级
- MAX_PRIORITY:10
- MIN _PRIORITY:1
- NORM_PRIORITY:5 -->默认优先级
-
如何获取和设置当前线程的优先级:
- getPriority():获取线程的优先级
- setPriority(int p):设置线程的优先级
- 说明:高优先级的线程要抢占低优先级线程cpu的执行权。但是只是从概率上讲,高优先级的线程高概率的情况下被执行。并不意味着只当高优先级的线程执行完以后,低优先级的线程才执行。
/**
* @author tao
* @create 2020-11-18 16:43
* 1. start():启动当前线程;调用当前线程的run()
* 2. run(): 通常需要重写Thread类中的此方法,将创建的线程要执行的操作声明在此方法中
* 3. currentThread():静态方法,返回执行当前代码的线程
* 4. getName():获取当前线程的名字
* 5. setName():设置当前线程的名字 或者使用构造器
* 6. yield():释放当前cpu的执行权
* 7. join():在线程a中调用线程b的join(),此时线程a就进入阻塞状态,直到线程b完全执行完以后,线程a才结束阻塞状态。
* 8. stop():已过时。当执行此方法时,强制结束当前线程。
* 9. sleep(long millitime):让当前线程“睡眠”指定的millitime毫秒。在指定的millitime毫秒时间内,当前线程是阻塞状态。
* 10. isAlive():判断当前线程是否存活
*
*/
class HelloThread extends Thread{
@Override
public void run() {
for (int i = 0; i < 100; i++) {
if(i%2 == 0){
// try {
// sleep(200);//0.2秒输出一次
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
System.out.println(Thread.currentThread().getName()+":"+getPriority()+":"+i);
}
if (i==20){
yield();
}
}
}
public HelloThread(String name){
super(name);
}
}
public class ThreadMethod {
public static void main(String[] args) {
HelloThread test1 =new HelloThread("Thread:1");//构造器命名
// test1.setName("线程1");
// test1.setPriority(Thread.MAX_PRIORITY);
test1.setPriority(10);//设置线程1的优先级为10(最大优先级)
test1.start();
Thread.currentThread().setPriority(Thread.MIN_PRIORITY);//设置主线程优先级为1
Thread.currentThread().setName("主线程");//给主线程命名
for (int i = 0; i < 100; i++) {
if(i%2 != 0){
System.out.println(Thread.currentThread().getName()+":"+test1.getPriority()+":"+i);
}
// test1.yield();
// Thread.yield();
//
// if(i == 19){
// try {
// test1.join();//主线程从19开始就开始执行分线程,直到分线程结束再执行未执行的主线程
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// }
}
}
}
线程通信:wait() / notify() / notifyAll() :此三个方法定义在Object类中的。
3. 线程的分类
Java中的线程分为两类:一种是守护线程,一种是用户线程。
它们在几乎每个方面都是相同的,唯一的区别是判断JVM何时离开。
守护线程是用来服务用户线程的,通过在start()方法前调用 thread.setDaemon(true)可以把一个用户线程变成一个守护线程。
Java垃圾回收就是一个典型的守护线程。
若JVM中都是守护线程,当前JVM将退出。
形象理解:兔死狗烹,鸟尽弓藏
4. Thread的生命周期
JDK中用Thread.State类定义了线程的几种状态
要想实现多线程,必须在主线程中创建新的线程对象。Java语言使用Thread类 及其子类的对象来表示线程,在它的一个完整的生命周期中通常要经历如下的五 种状态:
- 新建: 当一个Thread类或其子类的对象被声明并创建时,新生的线程对象处于新建 状态
- 就绪:处于新建状态的线程被start()后,将进入线程队列等待CPU时间片,此时它已 具备了运行的条件,只是没分配到CPU资源
- 运行:当就绪的线程被调度并获得CPU资源时,便进入运行状态, run()方法定义了线 程的操作和功能
- 阻塞:在某种特殊情况下,被人为挂起或执行输入输出操作时,让出 CPU 并临时中 止自己的执行,进入阻塞状态
- 死亡:线程完成了它的全部工作或线程被提前强制性地中止或出现异常导致结束
图示:
说明:
-
生命周期关注两个概念:状态、相应的方法
-
关注:状态a–>状态b:哪些方法执行了(回调方法)
某个方法主动调用:状态a–>状态b -
阻塞:临时状态,不可以作为最终状态
死亡:最终状态。