Java 并发库

可用

Java 中的多线程

Java 虚拟机支持并行计算。所有计算都可以在一个或多个线程的上下文中执行。我们可以轻松地为多个线程设置对同一资源或对象的访问,以及设置一个线程来执行单个代码块。

对于分配有多个线程的资源,任何开发人员都需要在读取和写入操作期间与线程同步工作。

重要的是,在访问资源时,您拥有最新的数据,以便另一个线程可以更改它并获得最新的信息。即使我们以银行账户为例,在钱到账之前,您无法使用它,因此始终拥有最新数据很重要。Java 具有用于同步和管理线程的特殊类。

线程对象

这一切都从主(main)线程开始,也就是说,至少你的程序已经有一个正在运行的线程。主线程可以使用CallableRunnable创建其他线程。创建仅在返回结果上有所不同,Runnable不返回结果并且不能抛出已检查的异常。因此,您获得了一个利用文件构建高效工作的好机会,但这是非常危险的,您需要小心。

也可以在单独的 CPU 核心上安排线程执行。系统可以轻松地在线程之间移动并通过正确的设置执行特定的线程:即读取数据的线程首先执行,一旦我们有数据,然后我们将其传递给负责验证的线程,之后我们将它传递给线程以执行一些业务逻辑,然后一个新线程将它们写回。在这种情况下,4 个线程轮流处理数据,一切都会比一个线程更快。每个这样的流都被转换为本机 OS 流,但如何转换取决于 JVM 实现。

Thread类用于创建和使用线程。它有标准的控制机制,也有抽象的机制,例如java.util.concurrent中的类和集合。

Java中的线程同步

通过共享对对象的访问来提供通信。这样很有效,但同时工作时也很容易出错。错误有两种情况:线程干扰 - 当另一个线程干扰您的线程时,以及内存一致性错误 - 内存一致性。为了解决和防止这些错误,我们有不同的同步方法。

Java 中的线程同步由监视器处理,这是一种高级机制,一次只允许一个线程执行受同一监视器保护的代码块。监视器的行为是根据锁来考虑的;一台显示器 - 一把锁。

同步有几个要点需要注意。第一点是互斥——只有一个线程可以拥有监视器,因此监视器上的同步意味着一旦一个线程进入监视器保护的同步块,其他线程就不能进入监视器保护的块。这个监视器直到第一个线程退出同步块。即多个线程不能同时访问同一个同步块。

但同步不仅仅是互斥。同步确保在同步块之前或同步块内写入内存的数据对同一监视器上同步的其他线程可见。退出块后,我们释放监视器,另一个线程可以抓住它并开始执行这段代码。

当一个新线程捕获监视器时,我们可以访问并执行该代码块,并且在那个时间点将从主内存加载变量。然后我们可以看到之前版本的监视器显示的所有条目。

如果字段被声明为volatile或由在任何读写之前获取的唯一锁保护,则对该字段的读写是原子操作。但是如果仍然遇到错误,那么你会得到一个关于重新排序的错误(改变顺序,重新排序)。它在不正确同步的多线程程序中表现出来,其中一个线程可以观察到其他线程产生的效果。

线程的互斥和同步的作用,即只有进入隐式获取锁的synchronized块或方法,或者显式获取锁,才能实现它们的正确运行。我们将在下面讨论它。这两种工作方式都会影响您的记忆力,重要的是不要忘记使用volatile变量。

Java 中的可变字段

如果一个变量被标记为volatile,它是全局可用的。这意味着如果一个线程访问一个volatile变量,它将在使用缓存中的值之前获取它的值。

写入工作类似于监视器释放,读取工作类似于监视器捕获。访问是在“之前执行”类型的关系中执行的。如果你弄明白了,当线程 A 访问一个volatile变量时,所有对线程 B 可见的就是线程 B 的变量。也就是说,你保证不会丢失来自其他线程的更改。

volatile变量是原子的,也就是说,当读取这样的变量时,使用与获取锁时相同的效果——内存中的数据被声明为无效或不正确,然后再次从内存中读取volatile变量的值。写入时,使用对内存的影响,释放锁时也是如此——一个易失性字段被写入内存。

Java并发

如果你想制作一个超级高效的多线程应用程序,你必须使用JavaConcurrent库中的类,它们位于java.util.concurrent包中。

该库非常庞大,功能各不相同,所以让我们看一下里面的内容并将其分为一些模块:

Java并发

并发集合是一组用于在多线程环境中工作的集合。与阻止访问整个集合的基本包装器 Collections.synchronizedList 不同,锁用于数据段或无等待算法用于并行读取数据。

队列- 用于在多线程环境中工作的非阻塞和阻塞队列。非阻塞队列专注于速度和操作而不阻塞线程。当您需要“减慢” ProducerConsumer线程时,阻塞队列适合工作。比如在某些条件不满足的情况下,队列为空或者满,或者没有空闲的Consumer'a

同步器是用于同步线程的实用工具。它们是“并行”计算的有力武器。

Executors是一个更方便和容易创建线程池的框架,很容易设置异步任务的调度和获取结果。

锁相对于基本的synchronized wait notify notifyAll ,是很多灵活的线程同步机制。

原子是可以支持对基元和引用的原子操作的类。

评论
  • 受欢迎
你必须先登录才能发表评论
此页面还没有任何评论