第一个示例,非阻塞计数器。
CAS,比较并交换即Compare-And-Swap。假设CAS有3个操作数--内存位置V、旧的预测值A和新值B,那么它的典型模式为:首先从V中读取值A,由A生成新值B,然后使用CAS原子化地把V的值改成B,并且期间不能有其他线程改变V的值,因为CAS能够发现来自其他线程的干扰。
- 代码 1 使用CAS实现的非阻塞计数器
- @ThreadSafe
- public class CasCounter {
- private SimulatedCAS value;
- public int getValue() {
- return value.get();
- }
- public int increment() {
- int v;
- do {
- v = value.get(); @1
- }
- while (v != value.compareAndSwap(v, v + 1)); @2
- return v + 1;
- }
- }
- 代码 2 模拟CAS操作
- @ThreadSafe
- public class SimulatedCAS {
- @GuardedBy("this") private int value;
- public synchronized int get() { return value; }
- public synchronized int compareAndSwap(int expectedValue,
- int newValue) {
- int oldValue = value;
- if (oldValue == expectedValue)
- value = newValue;
- return oldValue;
- }
- public synchronized boolean compareAndSet(int expectedValue,
- int newValue) {
- return (expectedValue
- == compareAndSwap(expectedValue, newValue));
- }
- }
假设有两个线程,同时执行到 @1 ,获得了value的旧值 ;然后同时执行到 @2 , 根据原则“ 当多个线程试图使用CAS同时更新相同的变量时,其中一个会胜出,并更新变量的值,而其他线程都会失败,重新尝试。 ”可知,其中一个线程完成了加1操作,而另一个线程失败,重新do循环。让我们细细体会一下这个原则是怎么得到的: 一个线程完成了加1操作后,另一个线程使用CAS时,旧的预期值没有变但内存位置V的值已经更新了,所以此时V的值不等于旧的预期值而导致失败!
第二个示例,非阻塞栈
- 代码3 使用Treiber算法的非阻塞栈
- @ThreadSafe
- public class ConcurrentStack <E> {
- AtomicReference<Node<E>> top = new AtomicReference<Node<E>>();
- public void push(E item) {
- Node<E> newHead = new Node<E>(item);
- Node<E> oldHead;
- do {
- oldHead = top.get();
- newHead.next = oldHead; @1
- } while (!top.compareAndSet(oldHead, newHead)); @2
- }
- public E pop() {
- Node<E> oldHead;
- Node<E> newHead;
- do {
- oldHead = top.get();
- if (oldHead == null)
- return null;
- newHead = oldHead.next;
- } while (!top.compareAndSet(oldHead, newHead));
- return oldHead.item;
- }
- private static class Node <E> {
- public final E item;
- public Node<E> next;
- public Node(E item) {
- this.item = item;
- }
- }
- }
注: AtomicReference<V>
compareAndSet ( V expect, V update)
若当前值与期望值expect相等时,原子化地将update值赋给当前值。
假设有两个线程,同时执行到 @1 ,获得了 栈顶元素,并创建了一个新节点指向当前栈顶;然后同时执行到 @2 , 根据原则“ 当多个线程试图使用CAS同时更新相同的变量时,其中一个会胜出,并更新变量的值,而其他线程都会失败,重新尝试。 ”可知,其中一个线程完成了插入操作,而另一个线程失败,重新do循环。让我们细细体会一下这个原则是怎么得到的:一个线程完成了插入操作后,另一个线程使用CAS时,旧的预期值没有变但当前栈顶的值已经更新了,所以此时栈顶的值不等于旧的预期值而导致失败!
第 三 个示例,非阻塞 链表
, Courier, mono, serif; font-size: 12px; background-color: #e7e5dc; width: 866px; margin-top: 18px !important; margin-right: 0px !important; margin-bottom: 18px !important; margin-
分享到:
相关推荐
Java并发编程是多线程环境下确保程序正确执行的关键技术,其中原子变量和非阻塞同步机制扮演着重要角色。非阻塞算法不同于传统的基于锁的同步机制,它们允许线程在不阻塞其他线程的情况下进行操作,提高了系统的并发...
重点讨论了C语言程序运行时的内存布局、多种上下文切换场景(包括函数调用、异常与中断处理、系统调用、进程上下文切换、线程上下文切换和虚拟机上下文切换)、以及常用的同步机制(包括基于互斥的同步机制、非阻塞...
理解同步/异步与阻塞/非阻塞的区别后,我们可以进一步探讨这两种机制的组合应用。 1. **同步阻塞**:最常见的组合之一,适用于简单且对实时性要求不高的应用场景。例如,使用阻塞式的方法读取文件或数据库查询。 2...
在实际应用中,同步和异步关注的是通知消息的机制,而阻塞与非阻塞关注的是程序等待消息时的状态。同步和异步决定了调用者是等待函数返回结果,还是继续执行其他操作。阻塞与非阻塞则决定了调用者是否在等待过程中...
Socket编程中的阻塞与非阻塞、同步与异步是两个独立的概念,它们涉及的是不同层面的操作机制。这里我们将详细探讨这两个概念以及I/O模型。 首先,同步与异步是客户端(C端)调用服务端(S端)时的行为模式。同步...
同步、异步、阻塞与非阻塞 在计算机科学中,同步、异步、阻塞与非阻塞是四个紧密相关的概念,它们都是关于任务或进程之间的交互和通信方式的描述。下面将对这四个概念进行详细的介绍和比较。 同步(Synchronous) ...
Java并发编程实战,第1章 简介,第2章 线程安全性 第3章 对象的共享 第4章 对象的组合 第5章 基础构建模块 第6章 任务执行 第7章 取消与关闭 第8章 ... 第15章 原子变量与非阻塞同步机制 第16章 Java内存模型
用一个最简单的例子说明异步非阻塞Socket的基本原理和工作机制
传统的基于锁的同步机制(如清单1所示的Counter)在高并发环境下可能会导致线程阻塞。当多个线程同时尝试获取同一锁时,只有一个线程能成功,其他线程会被挂起,等待锁的释放。这种阻塞会导致线程上下文切换,带来...
本文将深入探讨非阻塞的锁机制,特别是在“Linux驱动开发之旅(三)”中提及的3_mutex,这种锁机制允许任务在无法获取锁时立即返回,而不是等待。这种方式可以提高系统的响应性和效率,特别是在实时性要求较高的系统...
2. 非阻塞模式:非阻塞模式允许程序在等待数据传输时执行其他任务,提高程序的并发性。这种方式需要使用多线程或异步处理机制,以确保程序的运行不会因等待串口操作而中断。虽然实现起来相对复杂,但在需要高效处理...
**同步机制在JAVA中的应用与实现** 在计算机科学领域,特别是在多线程编程中,同步机制扮演着至关重要的角色。操作系统课程设计中,理解和实践这一概念对于计算机专业的学生来说是必要的。本报告将深入探讨Java语言...
非阻塞算法是一种在多线程编程中用于访问共享资源的策略,与传统的阻塞算法相比,它不依赖于锁或者其他同步机制来确保数据的一致性。非阻塞算法的核心思想是让线程在无法立即完成操作时,不进入等待状态,而是尝试...
在计算机编程,特别是网络编程中,同步、异步、阻塞和非阻塞是四个关键的概念,它们描述了程序执行时处理任务的方式。 同步是一种调用模式,它要求调用者在等待结果返回之前不能继续执行其他任务。例如,当你调用`...
本文将详细解析标题为“C++封装类CWSocket(多线程 非阻塞)”的项目,以及其在实际应用中的重要性和实现方式。 首先,我们来理解“CWSocket”这个类。CWSocket是C++中一个自定义的类,它对标准的socket API进行了...
线程是操作系统中并行执行的实体,它们共享同一进程的资源,如内存和打开的文件。...在设计多线程程序时,应尽量减少阻塞,充分利用非阻塞同步机制,并确保正确地管理线程状态,以防止死锁和资源争抢。
在IT领域,尤其是网络编程中,"阻塞"与"非阻塞"、"同步"与"异步"是四个非常关键的概念。这些概念主要应用于I/O操作,特别是涉及套接字(socket)通信时。下面将详细解释这些概念以及它们之间的区别。 **阻塞与非...
### 同步与异步——阻塞与非阻塞型IO详解 #### 一、引言 在计算机科学中,I/O(输入/输出)操作是任何程序与外部世界交互的基础。根据I/O操作的不同特性,可以将其分为四大类:同步阻塞IO、同步非阻塞IO、异步阻塞...
在IT领域,特别是网络编程中,我们经常遇到“同步”、“异步”、“阻塞”和“非阻塞”这些概念。这些术语是理解和优化应用程序性能的关键,特别是涉及到客户端(C端)与服务器(S端)之间的通信时。 首先,让我们...
Java同步机制是多线程编程中确保数据一致性与正确性的关键。在Java中,主要有两种同步机制:内置的`synchronized`关键字以及基于`java.util.concurrent`包中的高级同步工具类。本文将深入探讨这些机制的底层实现,...