1、继承Thead类
1 package com.cn.donleo.thread.impl;
2
3 /**
4 * @author liangd
5 * date 2020-10-31 15:29
6 * code 继承Thread类
7 */
8 public class MyThreadByThread extends Thread {
9
10 /**
11 * 构造方法,继承父类可直接super
12 *
13 * @param name
14 */
15 MyThreadByThread(String name) {
16 super(name);
17 }
18
19 @Override
20 public void run() {
21 for (int i = 0; i < 50; i++) {
22 System.out.println("第" + i + "个 MyThread: " + getName());
23 }
24 }
25 }
2、测试类
1 package com.cn.donleo.thread.impl;
2
3 /**
4 * @author liangd
5 * date 2020-10-31 15:35
6 * code 测试Thread
7 */
8 public class TestThread {
9
10 /**
11 * 一、步骤
12 * 1、定义 Thread 类的子类 并重写该类的 Run 方法,该 run 方法的方法体就代表了该线程需要完成的任务
13 *
14 * 2、创建 Thread 类的实例,即创建了线程对象
15 *
16 * 3、调用线程的 start 方法来启动线程
17 *
18 * 二、start和run方法的区别
19 * 1、start
20 * 用start方法来启动线程,真正实现了多线程运行,这时无需等待run方法体代码执行完毕而直接继续执行下面的代码。
21 * 通过调用Thread类的 start()方法来启动一个线程,这时此线程处于就绪(可运行)状态,并没有运行,
22 * 一旦得到cpu时间片,就开始执行run()方法,这里方法 run()称为线程体,它包含了要执行的这个线程的内容,
23 * Run方法运行结束,此线程随即终止。
24 * 2、run
25 * run()方法只是类的一个普通方法而已,如果直接调用Run方法,程序中依然只有主线程这一个线程,
26 * 其程序执行路径还是只有一条,还是要顺序执行,还是要等待run方法体执行完毕后才可继续执行下面的代码,
27 * 这样就没有达到写线程的目的。
28 *
29 * 3、直接执行run方法
30 * myThread.run();
31 * 结果表示对创建的对象进行方法的调用,而没有开启线程,等于普通方法
32 * start方法,开启线程,是由cpu去自动分配线程调用
33 * 4、为什么要重写run方法?
34 * run方法是用来封装执行的代码
35 * @param args
36 */
37 public static void main(String[] args){
38 MyThreadByThread thread1 = new MyThreadByThread("线程1");
39 MyThreadByThread thread2 = new MyThreadByThread("线程2");
40
41 //线程执行,如果直接调用,相当于普通方法,没有开启线程,按顺序执行
42 // thread1.run();
43 // thread2.run();
44 //线程就绪,执行顺序有CPU调用,顺序会发生变化,可以设置执行优先级
45 thread1.start();
46 thread2.start();
47 /*
48 线程生命周期:
49 1、线程创建(new)
50 新创建了一个线程对象
51 2、线程就绪(Runnable)
52 1)线程对象创建后,其他线程调用了该对象的start()方法。
53 2)该状态的线程位于可运行线程池中,变得可运行,等待获取CPU的使用权
54 3)有执行资格,但是没有执行权力,但可以开始抢CPU的使用权力
55 3、线程运行(Running)
56 就绪状态的线程获取了CPU,执行程序代码
57 4、线程阻塞(Blocked)
58 阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。
59 直到线程进入就绪状态,才有机会转到运行状态。阻塞的情况分三种
60 (一)等待阻塞:运行的线程执行wait()方法,JVM会把该线程放入等待池中。(wait会释放持有的锁)
61 (二)同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入锁池中
62 (三)其他阻塞:运行的线程执行sleep()或join()方法,或者发出了I/O请求时,
63 JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,
64 线程重新转入就绪状态。(注意,sleep是不会释放持有的锁)
65 5、线程死亡(Dead)
66 线程执行完了或者因异常退出了run()方法,该线程结束生命周期
67 */
68 }
69 }