【从零开始学Java | 第四十篇】多线程

张开发
2026/4/19 19:25:45 15 分钟阅读

分享文章

【从零开始学Java | 第四十篇】多线程
目录前言一、进程和线程1.进程2.线程3.进程与线程对比二、什么是多线程三、Java中创建线程的方式1.继承Thread类2.实现Runnable接口3.实现Callable接口四、线程常用的成员方法1.普通方法①. currentThread()②. getName() 和 setName()③. sleep()2.线程的优先级①setDaemon()守护线程前言在 Java 开发中多线程是一个非常重要的知识点。无论是后端接口并发处理、定时任务、异步执行、文件上传下载还是高并发系统设计都离不开多线程相关知识。一、进程和线程想要了解线程首先要先理解进程。1.进程进程是操作系统进行资源分配的基本单位每个进程都有自己独立的内存空间。进程可以理解为正在运行的程序打开你电脑的任务管理器每一个条目就代表一个进程。2.线程线程是进程中的一条执行路径。一个进程中可以包含多个线程。3.进程与线程对比对比项进程线程概念正在运行的程序进程中的执行路径资源拥有独立内存空间共享进程内存资源开销创建和切换开销较大创建和切换开销较小关系一个进程可以包含多个线程一个线程必须属于某个进程稳定性进程间相对独立一个线程异常可能影响整个进程二、什么是多线程多线程指的是在同一个程序中同时运行多个线程来完成不同任务。三、Java中创建线程的方式Java中创建线程有三种方式继承Thread类实现Runnable接口实现Callable接口1.继承Thread类步骤自定义类继承Thread重写run()方法调用start()启动线程启动线程必须使用Thread类提供的start方法调用run只是调用了方法。自定义类继承Thread并重写run方法public class MyThread extends Thread{ Override public void run() { for (int i 0; i 100; i) { System.out.println(Thread.currentThread().getName() 正在执行); } } }调用start()启动线程public class Test { public static void main(String[] args) { MyThread mt1 new MyThread(); MyThread mt2 new MyThread(); mt1.start(); mt2.start(); } }2.实现Runnable接口相比继承Thread实现Runnable接口更实用。步骤自定义类实现Runnable接口重写run方法创建Thread类并调用start()启动线程自定义类实现Runnable接口并重写run方法public class MyRunnable implements Runnable{ Override public void run() { for (int i 0; i 100; i) { System.out.println(Thread.currentThread().getName() 正在执行); } } }创建Thread类相当于创建了一个线程传入重写了run方法的对象相当于告诉这个线程任务是什么public class Test { public static void main(String[] args) { MyRunnable mr new MyRunnable(); Thread t1 new Thread(mr); Thread t2 new Thread(mr); t1.start(); t2.start(); } }实现Runnable接口创建线程的优点避免 Java单继承限制更适合多个线程共享同一个任务对象任务和线程对象解耦结构更清晰3.实现Callable接口Runnable有两个限制没有返回值不能直接抛出受检异常如果线程任务需要返回结果可以使用Callable。说明CallableV的call()方法可以返回结果FutureTask可以接收Callableget()方法用于获取线程执行结果注意futureTask.get()会阻塞当前线程直到子线程执行完成并返回结果。因此我们需要创建一个FutureTask对象。创建自定义类实现Callable接口Callable后面的泛型要写为返回结果的类型。public class MyCallable implements CallableInteger { Override public Integer call() throws Exception { int sum 0; for (int i 1; i 100; i) { sum i; } System.out.println(Thread.currentThread().getName() 正在计算中……); return sum; } }创建FutureTask对象使用get方法得到结果public class Test { public static void main(String[] args) throws ExecutionException, InterruptedException { MyCallable mc new MyCallable(); FutureTaskInteger ft new FutureTask(mc); Thread t1 new Thread(ft); t1.start(); Integer i ft.get(); System.out.println(i); } }运行结果四、线程常用的成员方法方法名说明String getName()返回此线程的名称void setName(String name)设置线程的名字构造方法也可以设置名字staticThread currentThread()获取当前的线程对象staticvoid sleep(long time)让线程休眠指定的时间单位为毫秒setPriority(int newPriority)设置线程的优先级final int getPriority()获取线程的优先级final void setDaemon(boolean on)设置为守护线程publicstaticvoid yield()礼让线程/出让线程publicstaticvoid join()插入线程/插队线程1.普通方法①.currentThread()获取当前正在执行的线程对象。System.out.println(Thread.currentThread().getName());②.getName()和setName()获取和设置线程名称。Thread thread new Thread(() - { System.out.println(Thread.currentThread().getName()); }); thread.setName(my-thread); thread.start();③.sleep()让当前线程暂停指定时间。try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); }2.线程的优先级Java 线程可以设置优先级thread.setPriority(Thread.MAX_PRIORITY);常见优先级Thread.MIN_PRIORITY // 1 Thread.NORM_PRIORITY // 5 Thread.MAX_PRIORITY // 10但是线程优先级只是给线程调度器的建议并不保证高优先级线程一定先执行。①setDaemon()守护线程线程分为两类用户线程User Thread和守护线程Daemon Thread。用户线程就是我们平时创建的普通线程包括main主线程。只要还有一个用户线程在运行JVMJava 虚拟机就不会退出。守护线程顾名思义它是默默在后台提供通用服务的线程比如最经典的垃圾回收器 GC 线程。它的生命周期完全依赖于用户线程。当所有的用户线程都执行完毕后无论守护线程是否还在执行JVM 都会立刻强制退出守护线程也会随之死亡。示例public class DaemonDemo01 { public static void main(String[] args) { Thread daemonThread new Thread(() - { int count 0; // 这是一个死循环 while (true) { System.out.println(守护线程正在后台默默运行... (count)); try { Thread.sleep(500); // 每0.5秒执行一次 } catch (InterruptedException e) { e.printStackTrace(); } } }); daemonThread.setName(守护线程); daemonThread.setDaemon(true); daemonThread.start(); try { System.out.println(Thread.currentThread().getName() 开始执行任务...); Thread.sleep(2000); // 主线程只运行 2 秒 System.out.println(Thread.currentThread().getName() 执行完毕准备退出。); } catch (InterruptedException e) { e.printStackTrace(); } } }运行结果

更多文章