做外贸怎样浏览国外网站,为什么建设银行网站打不开,旅游网站开发数据库,高价词网站源码Java多线程编程#xff1a;实现并发处理的高效利器
作者#xff1a;Stevedash
发表于#xff1a;2023年8月13日 20点45分
来源#xff1a;Java 多线程编程 | 菜鸟教程 (runoob.com)
在计算机领域#xff0c;多线程编程是一项重要的技术#xff0c;可以使程序同时执…Java多线程编程实现并发处理的高效利器
作者Stevedash
发表于2023年8月13日 20点45分
来源Java 多线程编程 | 菜鸟教程 (runoob.com)
在计算机领域多线程编程是一项重要的技术可以使程序同时执行多个任务充分利用计算资源提高系统的性能和响应能力。Java作为一门广泛应用的编程语言提供了丰富的多线程编程支持使得开发人员可以轻松实现并发处理。本篇博客将向您介绍Java多线程编程的基本概念、创建线程的方式、线程同步和线程通信等内容同时还会涉及到线程的生命周期、线程的优先级和线程的常用方法。
多线程编程的优势
多线程编程在提高程序性能、资源利用率和响应速度方面具有明显的优势。通过充分利用多核处理器可以在同一时刻处理多个任务提高系统的整体吞吐量。此外多线程还可以用于实现一些需要并发执行的场景如并发请求处理、数据采集、实时计算等。
创建线程的方式
Java多线程编程有三种常见的方式来创建线程 继承Thread类 创建一个类继承Thread类并重写run()方法来定义线程要执行的任务。 实现Runnable接口 创建一个实现Runnable接口的类并实现run()方法然后通过Thread类的构造方法创建线程对象。 实现Callable接口 创建一个实现Callable接口的类并实现call()方法可以获取线程执行后的返回值。
每种方式都有其特点选择合适的方式取决于具体需求。使用继承Thread类的方式编写简单但由于Java不支持多重继承可能限制了其他类的继承。而实现Runnable或Callable接口的方式可以更灵活地管理线程。 线程的生命周期
线程是一个动态执行的过程它也有一个从产生到死亡的过程。
下图显示了一个线程完整的生命周期。
线程的生命周期可以分为以下几个阶段
新建状态New 使用 new 关键字和 Thread 类或其子类建立一个线程对象后该线程对象就处于新建状态。它保持这个状态直到程序 start() 这个线程。就绪状态Runnable 当调用线程的start()方法后线程进入就绪状态就绪状态的线程处于就绪队列中要等待JVM里线程调度器的调度等待获取CPU时间片执行。运行状态Running 如果就绪状态的线程获取 CPU 资源就可以执行 run()此时线程便处于运行状态。处于运行状态的线程最为复杂它可以变为阻塞状态、就绪状态和死亡状态。阻塞状态Blocked **如果一个线程执行了sleep睡眠、suspend挂起等方法失去所占用资源之后该线程就从运行状态进入阻塞状态。**在睡眠时间已到或获得设备资源后可以重新进入就绪状态。可以分为三种 等待阻塞运行状态中的线程执行 wait() 方法使线程进入到等待阻塞状态。同步阻塞线程在获取 synchronized 同步锁失败(因为同步锁被其他线程占用)。其他阻塞通过调用线程的 sleep() 或 join() 发出了 I/O 请求时线程就会进入到阻塞状态。当sleep() 状态超时join() 等待线程终止或超时或者 I/O 处理完毕线程重新转入就绪状态。 死亡状态:Terminated 一个运行状态的线程完成任务或者其他终止条件发生时又或者当线程的run()方法执行完毕线程进入终止状态。 线程的优先级
每个线程都有一个优先级用于指示线程在竞争CPU时间片时的优先顺序。线程的优先级分为1到10其中1为最低优先级10为最高优先级。可以使用setPriority()方法设置线程的优先级但并不能保证优先级高的线程一定会先执行。**默认情况下每一个线程都会分配一个优先级 NORM_PRIORITY5。**具有较高优先级的线程对程序更重要并且应该在低优先级的线程之前分配处理器资源。但是线程优先级不能保证线程执行的顺序而且非常依赖于平台。 线程的常用方法
Java提供了一些常用的线程方法用于管理线程的执行和状态 start() 启动线程使其进入就绪状态。 join() 等待线程执行完毕。 sleep() 使线程休眠一段时间。 yield() 让出CPU时间片让其他线程执行。 isAlive() 判断线程是否还存活。
示例代码
以下是一个简单的Java程序演示了如何创建并启动多个线程并使用线程的优先级和常用方法
public class MultiThreadDemo {public static void main(String[] args) {Thread thread1 new Thread(new MyRunnable(Thread 1));Thread thread2 new Thread(new MyRunnable(Thread 2));thread1.setPriority(Thread.MAX_PRIORITY);thread2.setPriority(Thread.MIN_PRIORITY);thread1.start();thread2.start();try {thread1.join(); // 等待thread1执行完毕thread2.join(); // 等待thread2执行完毕} catch (InterruptedException e) {e.printStackTrace();}System.out.println(主线程结束);}//实现Runnable接口创建线程static class MyRunnable implements Runnable {private String name;public MyRunnable(String name) {this.name name;}//通过Callable接口和Future创建线程static class MyCallable implements CallableInteger {private String name;public MyCallable(String name) {this.name name;}Overridepublic Integer call() throws Exception{//...return Integer;}//继承Thread类创建线程 三选一static class MyThread extends Thread{private String name;public MyCallable(String name) {this.name name;}}//必须要重写run方法Overridepublic void run() {for (int i 1; i 5; i) {System.out.println(name : i);try {Thread.sleep(1000); // 休眠1秒} catch (InterruptedException e) {e.printStackTrace();}}}}
}下面是Thread 方法
下表列出了Thread类的一些重要方法
序号方法描述1public void start() 使该线程开始执行Java 虚拟机调用该线程的 run 方法。2public void run() 如果该线程是使用独立的 Runnable 运行对象构造的则调用该 Runnable 对象的 run 方法否则该方法不执行任何操作并返回。3public final void setName(String name) 改变线程名称使之与参数 name 相同。4public final void setPriority(int priority) 更改线程的优先级。5public final void setDaemon(boolean on) 将该线程标记为守护线程或用户线程。6public final void join(long millisec) 等待该线程终止的时间最长为 millis 毫秒。7public void interrupt() 中断线程。8public final boolean isAlive() 测试线程是否处于活动状态。
上述方法是被 Thread 对象调用的下面表格的方法是 Thread 类的静态方法。
序号方法描述1public static void yield() 暂停当前正在执行的线程对象并执行其他线程。2public static void sleep(long millisec) 在指定的毫秒数内让当前正在执行的线程休眠暂停执行此操作受到系统计时器和调度程序精度和准确性的影响。3public static boolean holdsLock(Object x) 当且仅当当前线程在指定的对象上保持监视器锁时才返回 true。4public static Thread currentThread() 返回对当前正在执行的线程对象的引用。5public static void dumpStack() 将当前线程的堆栈跟踪打印至标准错误流。 重点了解一下SetDeamon()标记成守护线程或者用户线程
基本概念
守护线程Daemon Thread是一种在后台运行的线程它的存在不会阻止程序的终止。与之相对用户线程User Thread是主要用于执行应用程序逻辑的线程“如果所有的用户线程都执行完毕JVM 就会退出而不管守护线程是否还在运行。”
在 Java 中我们可以通过 setDaemon(true) 方法将一个线程设置为守护线程。**默认情况下线程都是用户线程不会影响程序的终止。**如果想要使用守护线程可以在创建线程后调用 setDaemon(true) 来设置它为守护线程。 守护线程的主要作用有以下几点
后台任务执行 守护线程通常用于执行一些不需要持续运行的后台任务如垃圾回收Garbage Collection、内存管理等。通过将这些任务放在守护线程中可以在主要任务执行完毕后自动进行清理等工作提高系统的整体性能和资源利用率。资源管理 守护线程可以用于监控和管理一些资源如数据库连接池、网络连接等。当用户线程都结束时守护线程可以负责关闭这些资源防止资源泄露和浪费。周期性任务 守护线程还可以用于执行周期性的任务如定时器任务。这些任务可以在“后台周期性地执行而不影响主要业务逻辑的进行。”
PS这很重要基本上就是守护线程的重点守护线程在程序终止时会突然中断因此不应该在它们的代码中进行需要确保完整性的操作。另外守护线程不应该依赖于特定的执行顺序因为它们的执行可能会受到系统资源调度的影响。 三种创建线程的方式对比 继承 Thread 类 创建线程的方式之一是继承 Thread 类并重写 run 方法来定义线程的任务逻辑。优点简单不需要额外的类来实现接口。缺点由于 Java 不支持多继承因此如果已经继承了其他类则无法再使用这种方式创建线程。示例代码 class MyThread extends Thread {public void run() {// 线程执行的任务逻辑}
}public class ThreadExample {public static void main(String[] args) {MyThread thread new MyThread();thread.start();}
}实现 Runnable 接口 另一种创建线程的方式是实现 Runnable 接口并将实现类的实例传递给 Thread 类的构造函数。优点可以避免继承单一父类的限制同时更灵活可以实现多个接口。缺点相对于继承 Thread 类需要额外的类来实现接口。示例代码 class MyRunnable implements Runnable {public void run() {// 线程执行的任务逻辑}
}public class RunnableExample {public static void main(String[] args) {Thread thread new Thread(new MyRunnable());thread.start();}
}使用 Callable 和 Future 使用 Callable 接口可以创建一个带有返回结果的任务。Future 接口可以用于获取任务的执行结果。优点可以获取任务的返回结果能够捕获任务抛出的异常。示例代码 import java.util.concurrent.*;class MyCallable implements CallableInteger {public Integer call() throws Exception {// 线程执行的任务逻辑return 42;}
}public class CallableExample {public static void main(String[] args) {ExecutorService executor Executors.newSingleThreadExecutor();FutureInteger future executor.submit(new MyCallable());try {int result future.get();System.out.println(任务执行结果 result);} catch (Exception e) {e.printStackTrace();} finally {executor.shutdown();}}
}三种创建线程方式对比小结
采用实现 Runnable、Callable 接口的方式创建多线程时线程类只是实现了 Runnable 接口或 Callable 接口还可以继承其他类。使用继承 Thread 类的方式创建多线程时编写简单如果需要访问当前线程则无需使用 Thread.currentThread() 方法直接使用 this 即可获得当前线程。继承 Thread 类和实现 Runnable 接口是最基本的方式而使用 Callable 和 Future 可以获得更多的控制和返回结果的能力。 线程的几个主要概念
在多线程编程时你需要了解以下几个概念
线程同步线程间通信线程死锁线程控制挂起、停止和恢复 注意事项和进阶功能 多线程编程需要注意线程安全性和资源竞争问题合理使用同步机制来保证数据的一致性。 Java提供了线程池、并发集合等工具类来简化多线程编程提高效率和性能。 在处理复杂场景时可以使用Executor框架、Future接口等实现更高级的线程管理和任务调度。 总结
Java多线程编程是实现并发处理的有效手段可以提高程序性能和响应能力。通过学习线程创建方式、线程同步、线程通信、线程的生命周期、线程的优先级和线程的常用方法我们可以在应用程序中合理使用多线程来实现并发任务。
作者Stevedash
发表于2023年8月13日 20点45分
来源Java 多线程编程 | 菜鸟教程 (runoob.com)
注本文内容基于个人学习理解如有错误或疏漏欢迎指正。感谢阅读如果觉得有帮助请点赞和分享。