Java并发编程

一、定义

Java并发编程是指在Java应用程序中同时执行多个任务的能力。并发编程的出现主要是为了更有效地利用计算资源,特别是在多核处理器普遍存在的当代,通过并发执行可以显著提高程序的性能和响应速度。

Java并发编程涉及使用Java语言提供的多线程和同步机制来创建并发应用程序。在Java中,"线程"是并发执行的基本单位。Java提供了丰富的API来管理线程的生命周期、同步线程间的操作以及线程间的通信。

二、为什么会出现Java并发编程?

  1. 多核处理器:随着现代计算机多核处理器的普及,单个进程可以同时在多个处理器核心上运行多个线程,从而提高应用程序的执行效率。

  2. 资源利用:并发编程使得可以同时执行多个操作,这样可以更好地利用系统资源,避免CPU等待I/O操作(如读写文件、网络通信等)而闲置。

  3. 提高响应性:在用户界面应用程序中,通过并发执行可以使用户界面保持响应状态,同时在后台执行耗时任务,提升用户体验。

  4. 处理大量任务:对于需要同时处理大量独立任务的服务器应用程序,通过并发处理可以提高吞吐量和效率。

三、一般用什么来实现Java并发编程?

  1. Thread类:可以通过继承java.lang.Thread类并重写其run()方法来创建线程。

  2. Runnable接口:可以实现java.lang.Runnable接口并实现其run()方法,然后将Runnable实例传递给Thread对象来创建线程。

  3. Executor框架:Java 5引入了Executor框架,提供了线程池管理、任务调度等功能。通过使用Executors类的静态工厂方法可以创建不同类型的线程池。

  4. Future和Callablejava.util.concurrent.Future接口和java.util.concurrent.Callable接口提供了一种处理异步任务的方式,Callable允许任务返回结果。

  5. 同步器:Java的java.util.concurrent包(并发编程工具包的简称,处理线程的工具包,JDK1.5开始出现)还提供了各种同步器,如SemaphoreCountDownLatchCyclicBarrierPhaser,用于协调多个线程之间的同步。

  6. 并发集合java.util.concurrent包提供了并发集合,如ConcurrentHashMapConcurrentLinkedQueue等,它们在多线程环境下提供了更好的性能。

  7. 原子变量java.util.concurrent.atomic包提供了一组原子变量类,如AtomicIntegerAtomicLong等,用于在多线程环境中无锁的进行原子操作。

  8. Locksjava.util.concurrent.locks包提供了显式锁定机制,比如ReentrantLock,提供了比synchronized关键字更灵活的锁定操作。

并发编程是一个复杂且容易出错的领域,需要仔细设计来避免死锁、竞态条件、线程饥饿等问题。因此,理解Java并发编程的基础概念和最佳实践是非常重要的。

基本概念

1、进程

进程是在操作系统中正在运行的一个应用程序,程序一旦运行就是进程。也是操作系统分配资源和调度的基本单位。是一个运行中的程序的实例,拥有独立的内存空间。一个进程可以包含一个或多个线程。在Java中,当运行一个Java应用程序时,例如通过命令行使用java命令,操作系统为该应用程序启动了一个新的进程。

无论是启动一个Spring Boot项目还是运行一个包含main方法的简单测试类,操作系统都会为每个运行的Java应用程序创建一个独立的进程。

大的进程示例 - 启动Spring Boot项目

         当启动一个Spring Boot应用程序,例如使用命令行java -jar my-spring-boot-app.jar或者通过集成开发环境(IDE)中的启动配置,操作系统会创建一个新的Java进程。这个进程会加载Spring Boot框架以及应用程序的代码,并开始执行。Spring Boot应用程序通常是长时间运行的服务,它会监听网络请求并提供Web服务。在这个进程中,还可以创建多个线程来处理并发请求,执行后台任务等。

小的进程示例 - 运行含main方法的测试类

         即使是一个简单的Java类,只要包含一个main方法,当运行这个类时,比如通过命令行java Test或在IDE中直接运行,操作系统同样会为它创建一个新的进程。这个进程可能只做一些简单的任务,如运行一些单元测试或输出一些信息到控制台,然后很快结束。

这两个例子中的进程都拥有自己的独立内存空间,可以加载不同的类和资源,它们在操作系统层面是完全独立的。

下面是一个简单的Java类,它包含一个main方法,用于演示一个小的进程:

public class Test {
    public static void main(String[] args) {
        System.out.println("Running a simple test method.");
    }
}

当运行这个类时,Java虚拟机(JVM)会启动,操作系统会为其创建一个新的进程,然后在这个进程中执行main方法中的代码。执行完成后,进程结束,操作系统回收了分配给该进程的资源。

2、线程

线程系统分配处理器时间资源的基本单元,是进程之内独立运行的一个单元执行流,是程序执行的最小单位。Java中的线程是由java.lang.Thread类的一个实例来表示和控制的。可以通过操作系统线程来实现,也可以通过线程库在用户空间中实现,这取决于Java虚拟机的实现和宿主操作系统。

2.1线程的状态

在Java中,线程(Thread)可以处于不同的状态。Java线程状态由java.lang.Thread.State枚举定义,包括以下几种:

  1. NEW(新建): 线程刚被创建,但还没有调用start()方法。此时的线程尚未开始执行。

    Thread thread = new Thread(() -> { /* 任务代码 */ }); // 此时线程状态为 NEW
  2. RUNNABLE(可运行): 线程已经调用了start()方法,可能正在执行,也可能正在等待CPU分配时间片。在Java中,RUNNABLE状态包括了操作系统线程状态中的“运行中”和“就绪”两种情况。

    thread.start(); // 此时线程状态为 RUNNABLE
  3. BLOCKED(阻塞): 线程正在等待一个监视器锁(monitor lock)以进入一个同步块/方法,或者在已经进入同步块/方法后,再次尝试进入另一个同步块/方法。

    synchronized (object) { // 当前线程持有object的锁 // 其他线程试图进入这个同步块时会被阻塞 }
  4. WAITING(等待): 线程因为调用了Object.wait()Thread.join()LockSupport.park()等方法,正在无限期等待其他线程执行特定动作(通知或中断)。

    synchronized (object) { object.wait(); // 使当前线程进入 WAITING 状态 }
  5. TIMED_WAITING(计时等待): 线程因为调用了带有指定等待时间的Thread.sleep()Object.wait(long timeout)Thread.join(long millis)LockSupport.parkNanos()LockSupport.parkUntil()等方法,正在等待另一个线程执行动作或等待时间的到来。

    Thread.sleep(1000); // 使当前线程进入 TIMED_WAITING 状态
  6. TERMINATED(终止): 线程的run()方法已经执行完毕,或者线程被中断或抛出异常而结束,线程的执行已经完成。

    // 当run()方法执行完毕后,线程状态为 TERMINATED

线程的状态会在其生命周期中根据执行情况而变化,正确理解和使用这些状态对于实现多线程编程和调试是非常重要的。

2.2线程的创建和启动

简单了解线程-CSDN博客

  • 15
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值