资讯动态

【Java】多线程初阶

发布时间:2026/10/14 6:29:57 来源:尧图企业网站定制
认识线程概念线程是什么1线程就是一个执行流每个线程按顺序执行自身代码多个线程可以 “同时” 执行多份代码2银行例子公司办业务张三主线程叫李四、王五一起处理转账、发福利、缴社保3 个执行流共同完成同一个公司的任务这就是多线程。张三是主线程 (Main Thread)为什么要有线程1并发编程是刚需a单核 CPU 遇到性能瓶颈多核 CPU 需要并发程序才能充分利用算力b任务有 IO 等待场景线程等待 IO 的时候CPU 可以去执行别的任务不浪费时间2线程比进程更轻量a创建线程更快b销毁线程更快c操作系统调度线程更快3进阶优化线程池、协程进程和线程的区别银行举例多进程 多个客户各自办业务票据互相隔离多线程 同一个公司多个员工办业务票据共享4 种模型1单线程进程1 个进程里面只有 1 条执行流2单进程多线程1 个进程内部多条执行流3多个单线程进程多个独立进程每个进程只有 1 个线程4多个多线程进程多个独立进程每个进程内部都有多条线程Java 线程 和 OS 操作系统线程的关系1线程本质是操作系统内核提供的机制OS 提供 API如 Linux pthread 库给程序使用2Java 里的Thread类是对操作系统原生线程 API 的抽象和封装。Java 线程底层就是操作系统线程面试题1线程是什么线程是一条执行流多个线程可以并发执行代码同一个进程内线程共享内存资源2进程和线程区别①进程是资源分配最小单位线程是 CPU 调度最小单位②进程内存相互隔离同一进程线程共享内存③进程包含线程一个进程至少一个主线程④进程崩溃互不影响线程崩溃可能造成整个进程退出⑤线程创建销毁调度开销远小于进程更轻量。3为什么用多线程充分利用多核 CPUIO 等待时让 CPU 执行其他任务线程相比进程轻量开销更小。4Java Thread 和操作系统线程Java 的 Thread 封装了操作系统原生线程Java 线程本质就是操作系统线程。第一个多线程程序public class ThreadDemo { // 自定义线程类继承Thread private static class MyThread extends Thread{ Override public void run() { Random randomnew Random(); while(true) { //打印当前线程名字 System.out.println(Thread.currentThread().getName()); try { //休眠几秒 Thread.sleep(random.nextInt(10)); }catch(InterruptedException e) { e.printStackTrace(); } } } } public static void main(String[] args) { MyThread t1new MyThread(); t1.start(); //启动线程自动调用run() 方法 Random randomnew Random(); while(true) { // main 方法本身运行在主线程 ( main线程) System.out.println(Thread.currentThread().getName()); try { Thread.sleep(random.nextInt(10)); } catch (InterruptedException e) { e.printStackTrace(); } } } }线程概念1每个线程都是独立执行流多个线程并发执行操作系统快速切换看起来同时运行2这里一共两个线程amain主线程执行 main 函数里的 while 循环bt1自定义子线程执行 MyThread 里run()的 while 循环3注意调用 t1.start() 才是创建并启动线程不能直接调用 t1.run ()直接调用 run 只是普通方法调用不会创建新线程Thread.sleep()1让当前线程休眠指定毫秒进入阻塞状态2会抛出受检异常InterruptedException必须 try-catch 捕获3random.nextInt(10)生成[0,9]随机整数单位秒Thread.currentThread().getName()1获取当前正在执行代码的线程名称。a子线程默认名字Thread-0b主线程名字main2程序输出会交替打印 main 和 Thread-0顺序随机就是并发效果易错点1start()创建新线程由 JVM 自动调用run()开启多线程2run()线程要执行的任务代码直接调用只是普通方法不会新建线程创建线程的 5 种方式方式 1继承 Thread 类//继承Thread 方式创建线程 public static class MyThread extends Thread { // 重写run 方法线程执行任务 Override public void run() { System.out.println(这里是线程运行的代码); } } public static void main(String[] args) { // 创建自定义线程 MyThread tnew MyThread(); t.start(); //启动线程自动调用run方法 }要点1run()线程任务逻辑写线程要执行的代码2start()启动线程向操作系统申请创建线程然后自动执行 run ()不能直接调用 run ()直接调用只是普通方法不会创建新线程3在类内部this代表当前线程对象方式 2实现 Runnable 接口// 实现Runnable 接口 public static class MyRunnable implements Runnable{ //重写 run 方法 定义线程任务 Override public void run() { System.out.println(这里是线程运行的代码); } } public static void main(String[] args) { // 创建任务对象 MyRunnable myRunnable new MyRunnable(); //将任务对象传入Thread 构造器 创建线程对象 Thread t1new Thread(myRunnable); t1.start(); // 调用start 启动线程 }要点1Java 是单继承如果类已经继承别的类就只能用 Runnable 接口2this代表 MyRunnable 对象不是线程对象获取当前线程对象要用Thread.currentThread()两种方式对比简化写法匿名内部类 Lambda匿名内部类创建 Thread 子类public static void main(String[] args) { // 匿名内部类继承Thread 重写run方法 Thread t1new Thread() { Override public void run() { System.out.println(使用匿名内部类创建Thread 子类对象); } }; // 启动线程 t1.start(); }1new Thread(){ ... }a这是匿名内部类相当于快速创建一个继承Thread的子类类没有名字。b大括号{}里面重写父类 Thread 的run()方法run()存放线程要执行的任务。2t1.start()a调用start()JVM 会向操作系统申请创建新线程线程就绪后自动执行run()。b 如果写t1.run()只是普通方法调用不会开启新线程。匿名内部类创建 Runnablepublic static void main(String[] args) { //匿名内部类实现Runnable接口作为Thread的任务参数 Thread t2new Thread(new Runnable() { Override public void run() { System.out.println(使用匿名内部类创建 Runnable 子类对象); } }); t2.start(); }1new Runnable(){ ... }Runnable 是接口这里创建匿名内部类实现 Runnable 接口重写唯一抽象方法run()run()里面就是线程要执行的任务。2把这个匿名 Runnable 实例传入 Thread 构造方法Thread 内部会持有这个任务对象。3调用 t2.start()开启新线程线程调度后自动执行 Runnable 里面的run()。Lambda 表达式1Runnable 是函数式接口只有一个抽象方法可以用 lambda 简化public static void main(String[] args) { // 单行写法lambda 表达式 Thread t3new Thread(()- System.out.println(lambda创建线程)); // 多行写法需要大括号包裹 Thread t4new Thread(()- { System.out.println(lambda多行写法); System.out.println(第二行任务代码); }); // 启动线程 t3.start(); t4.start(); }2原理Runnable 是函数式接口只有一个抽象方法 run()所以支持 Lambda 表达式简写。a() - 代码 就代表实现 Runnable 的 run 方法。b()run 方法没有参数c-箭头符号分隔参数和方法体3两种 lambda 格式a单行语句可以省略大括号和 return() - System.out.println(lambda创建线程)a多条执行语句必须加上 {}() - { System.out.println(第一行); System.out.println(第二行); }4本质等价// lambda等价于前面的匿名Runnable Thread t2 new Thread(new Runnable() { Override public void run() { System.out.println(匿名Runnable); } });总结1start()和run()的区别arun()只是普通方法里面放任务代码直接调用不会开启新线程bstart()native 方法真正在 OS 创建线程线程就绪后自动调用 run ()2推荐优先使用Runnable Lambda解耦、不占用继承、代码简洁3线程启动只能调用start()一个线程对象只能 start 一次多次 start 抛异常

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑