Java实现多线程的三种方式(1) ------继承Thread类
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 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix