- Javascript Basics Tutorial
- Javascript - Home
- JavaScript - Overview
- JavaScript - Features
- JavaScript - Enabling
- JavaScript - Placement
- JavaScript - Syntax
- JavaScript - Hello World
- JavaScript - Console.log()
- JavaScript - Comments
- JavaScript - Variables
- JavaScript - let Statement
- JavaScript - Constants
- JavaScript - Data Types
- JavaScript - Type Conversions
- JavaScript - Strict Mode
- JavaScript - Reserved Keywords
- JavaScript Operators
- JavaScript - Operators
- JavaScript - Arithmetic Operators
- JavaScript - Comparison Operators
- JavaScript - Logical Operators
- JavaScript - Bitwise Operators
- JavaScript - Assignment Operators
- JavaScript - Conditional Operators
- JavaScript - typeof Operator
- JavaScript - Nullish Coalescing Operator
- JavaScript - Delete Operator
- JavaScript - Comma Operator
- JavaScript - Grouping Operator
- JavaScript - Yield Operator
- JavaScript - Spread Operator
- JavaScript - Exponentiation Operator
- JavaScript - Operator Precedence
- JavaScript Control Flow
- JavaScript - If...Else
- JavaScript - While Loop
- JavaScript - For Loop
- JavaScript - For...in
- Javascript - For...of
- JavaScript - Loop Control
- JavaScript - Break Statement
- JavaScript - Continue Statement
- JavaScript - Switch Case
- JavaScript - User Defined Iterators
- JavaScript Functions
- JavaScript - Functions
- JavaScript - Function Expressions
- JavaScript - Function Parameters
- JavaScript - Default Parameters
- JavaScript - Function() Constructor
- JavaScript - Function Hoisting
- JavaScript - Self-Invoking Functions
- JavaScript - Arrow Functions
- JavaScript - Function Invocation
- JavaScript - Function call()
- JavaScript - Function apply()
- JavaScript - Function bind()
- JavaScript - Closures
- JavaScript - Variable Scope
- JavaScript - Global Variables
- JavaScript - Smart Function Parameters
- JavaScript Objects
- JavaScript - Number
- JavaScript - Boolean
- JavaScript - Strings
- JavaScript - Arrays
- JavaScript - Date
- JavaScript - DataView
- JavaScript - Math
- JavaScript - RegExp
- JavaScript - Symbol
- JavaScript - Sets
- JavaScript - WeakSet
- JavaScript - Maps
- JavaScript - WeakMap
- JavaScript - Iterables
- JavaScript - Reflect
- JavaScript - TypedArray
- JavaScript - Template Literals
- JavaScript - Tagged Templates
- Object Oriented JavaScript
- JavaScript - Objects
- JavaScript - Classes
- JavaScript - Object Properties
- JavaScript - Object Methods
- JavaScript - Static Methods
- JavaScript - Display Objects
- JavaScript - Object Accessors
- JavaScript - Object Constructors
- JavaScript - Native Prototypes
- JavaScript - ES5 Object Methods
- JavaScript - Encapsulation
- JavaScript - Inheritance
- JavaScript - Abstraction
- JavaScript - Polymorphism
- JavaScript - Destructuring Assignment
- JavaScript - Object Destructuring
- JavaScript - Array Destructuring
- JavaScript - Nested Destructuring
- JavaScript - Optional Chaining
- JavaScript - Global Object
- JavaScript - Mixins
- JavaScript - Proxies
- JavaScript Versions
- JavaScript - History
- JavaScript - Versions
- JavaScript - ES5
- JavaScript - ES6
- ECMAScript 2016
- ECMAScript 2017
- ECMAScript 2018
- ECMAScript 2019
- ECMAScript 2020
- ECMAScript 2021
- ECMAScript 2022
- JavaScript Cookies
- JavaScript - Cookies
- JavaScript - Cookie Attributes
- JavaScript - Deleting Cookies
- JavaScript Browser BOM
- JavaScript - Browser Object Model
- JavaScript - Window Object
- JavaScript - Document Object
- JavaScript - Screen Object
- JavaScript - History Object
- JavaScript - Navigator Object
- JavaScript - Location Object
- JavaScript - Console Object
- JavaScript Web APIs
- JavaScript - Web API
- JavaScript - History API
- JavaScript - Storage API
- JavaScript - Forms API
- JavaScript - Worker API
- JavaScript - Fetch API
- JavaScript - Geolocation API
- JavaScript Events
- JavaScript - Events
- JavaScript - DOM Events
- JavaScript - addEventListener()
- JavaScript - Mouse Events
- JavaScript - Keyboard Events
- JavaScript - Form Events
- JavaScript - Window/Document Events
- JavaScript - Event Delegation
- JavaScript - Event Bubbling
- JavaScript - Event Capturing
- JavaScript - Custom Events
- JavaScript Error Handling
- JavaScript - Error Handling
- JavaScript - try...catch
- JavaScript - Debugging
- JavaScript - Custom Errors
- JavaScript - Extending Errors
- JavaScript Important Keywords
- JavaScript - this Keyword
- JavaScript - void Keyword
- JavaScript - new Keyword
- JavaScript - var Keyword
- JavaScript HTML DOM
- JavaScript - HTML DOM
- JavaScript - DOM Methods
- JavaScript - DOM Document
- JavaScript - DOM Elements
- JavaScript - DOM Forms
- JavaScript - Changing HTML
- JavaScript - Changing CSS
- JavaScript - DOM Animation
- JavaScript - DOM Navigation
- JavaScript - DOM Collections
- JavaScript - DOM Node Lists
- JavaScript Miscellaneous
- JavaScript - Ajax
- JavaScript - Async Iteration
- JavaScript - Atomics Objects
- JavaScript - Rest Parameter
- JavaScript - Page Redirect
- JavaScript - Dialog Boxes
- JavaScript - Page Printing
- JavaScript - Validations
- JavaScript - Animation
- JavaScript - Multimedia
- JavaScript - Image Map
- JavaScript - Browsers
- JavaScript - JSON
- JavaScript - Multiline Strings
- JavaScript - Date Formats
- JavaScript - Get Date Methods
- JavaScript - Set Date Methods
- JavaScript - Modules
- JavaScript - Dynamic Imports
- JavaScript - BigInt
- JavaScript - Blob
- JavaScript - Unicode
- JavaScript - Shallow Copy
- JavaScript - Call Stack
- JavaScript - Reference Type
- JavaScript - IndexedDB
- JavaScript - Clickjacking Attack
- JavaScript - Currying
- JavaScript - Graphics
- JavaScript - Canvas
- JavaScript - Debouncing
- JavaScript - Performance
- JavaScript - Style Guide
- JavaScript Useful Resources
- JavaScript - Questions And Answers
- JavaScript - Quick Guide
- JavaScript - Functions
- JavaScript - Resources
JavaScript - Atomics Objects
The Atomics object in JavaScript provides a set of static methods for performing atomic operations on SharedArrayBuffer objects. Atomic operations are operations that are guaranteed to be completed in a single step, without being interrupted by other threads. This makes them useful for implementing concurrent data structures and algorithms.
The Atomics object in JavaScript, as part of the ECMAScript standard, serves as a crucial tool for managing shared memory in a multi-threaded environment. Let's understand the basic concept of atomic operations in more detail:
Atomics Object
The Atomics object is a built-in JavaScript object that provides atomic operations on shared memory. It is designed to be used in a multi-threaded environment, where multiple threads or Web Workers may be concurrently accessing and modifying shared data.
The Essence of "Atomic"
In the context of the Atomics object, "atomic" signifies a crucial characteristic: it performs operations that are inherently indivisible. When we declare an operation as atomic; we imply its execution occurs continuously and uninterruptedly like a single unit. This quality is indispensable in preventing race conditions; these arise when concurrent operations' outcomes depend on their timing and sequence of execution.
Atomic Operations
Atomic operations are low-level operations on shared memory that are guaranteed to be executed as a single, uninterruptible unit. These operations include additions, subtractions, bitwise operations, exchanges, and more.
The Atomics object provides methods like add, sub, and, or, xor, load, store, exchange, and others, each corresponding to a specific atomic operation.
Sr.No. | Method & Description |
---|---|
1 | Atomics.add() Adds a specified value to the element at the specified index in the typed array. Returns the original value atomically. |
2 | Atomics.sub() Subtracts a specified value from the element at the specified index in the typed array. Returns the original value atomically. |
3 | Atomics.and() Performs an atomic bitwise AND operation on the element at the specified index in the typed array with the given value. Returns the original value atomically. |
4 | Atomics.or() Performs an atomic bitwise OR operation on the element at the specified index in the typed array with the given value. Returns the original value atomically. |
5 | Atomics.xor() Performs an atomic bitwise XOR operation on the element at the specified index in the typed array with the given value. Returns the original value atomically. |
6 | Atomics.load() Retrieves the value at the specified index in the typed array atomically. |
7 | Atomics.store() Stores the given value at the specified index in the typed array atomically. |
8 | Atomics.exchange() Swaps the value at the specified index in the typed array with a specified value. Returns the original value atomically. |
9 | Atomics. compareExchange() Compares the value at the specified index in the typed array with a provided expected value, and if they match, updates the value with a new value. Returns the original value atomically. |
10 | Atomics.wait() Atomically waits for a value at the specified index in the typed array to be a specific value and then returns. Allows for efficient coordination between threads. |
11 | Atomics.notify() Atomically notifies the wait queue associated with the specified index in the typed array. |
Examples
Example 1: Basic Usage of Atomics Operations
In this example, the Atomics object is demonstrated for its fundamental atomic operations on shared memory. These operations include addition, subtraction, bitwise AND, OR, XOR, loading, storing, exchanging, and compare-exchanging values. Each operation ensures the indivisibility of the executed unit, crucial for preventing race conditions in a multi-threaded environment.
Atomics.add()
// Shared memory setup const sharedBuffer = new SharedArrayBuffer(4); const sharedArray = new Int32Array(sharedBuffer); // Atomics.add() const originalAddValue = Atomics.add(sharedArray, 0, 10); console.log(`Atomics.add: Original value: ${originalAddValue}, New value: ${sharedArray[0]}`);
Output
Atomics.add: Original value: 0, New value: 10
Atomics.add()
// Shared memory setup const sharedBuffer = new SharedArrayBuffer(4); const sharedArray = new Int32Array(sharedBuffer); // Atomics.sub() const originalSubValue = Atomics.sub(sharedArray, 0, 5); console.log(`Atomics.sub: Original value: ${originalSubValue}, New value: ${sharedArray[0]}`);
Output
Atomics.sub: Original value: 10, New value: 5
Atomics.add()
// Shared memory setup const sharedBuffer = new SharedArrayBuffer(4); const sharedArray = new Int32Array(sharedBuffer); // Atomics.and() const originalAndValue = Atomics.and(sharedArray, 0, 0b1010); console.log(`Atomics.and: Original value: ${originalAndValue}, New value: ${sharedArray[0].toString(2)}`);
Output
Atomics.and: Original value: 5, New value: 0
Atomics.or()
// Shared memory setup const sharedBuffer = new SharedArrayBuffer(4); const sharedArray = new Int32Array(sharedBuffer); // Atomics.or() const originalOrValue = Atomics.or(sharedArray, 0, 0b1100); console.log(`Atomics.or: Original value: ${originalOrValue}, New value: ${sharedArray[0].toString(2)}`);
Output
Atomics.or: Original value: 0, New value: 1100
Atomics.xor()
// Shared memory setup const sharedBuffer = new SharedArrayBuffer(4); const sharedArray = new Int32Array(sharedBuffer); // Atomics.xor() const originalXorValue = Atomics.xor(sharedArray, 0, 0b0110); console.log(`Atomics.xor: Original value: ${originalXorValue}, New value: ${sharedArray[0].toString(2)}`);
Output
Atomics.xor: Original value: 12, New value: 1010
Atomics.load()
// Shared memory setup const sharedBuffer = new SharedArrayBuffer(4); const sharedArray = new Int32Array(sharedBuffer); // Atomics.load() const loadedValue = Atomics.load(sharedArray, 0); console.log(`Atomics.load: Loaded value: ${loadedValue}`);
Output
Atomics.load: Loaded value: 10
Atomics.store()
// Shared memory setup const sharedBuffer = new SharedArrayBuffer(4); const sharedArray = new Int32Array(sharedBuffer); // Atomics.store() Atomics.store(sharedArray, 0, 42); console.log(`Atomics.store: New value: ${sharedArray[0]}`);
Output
Atomics.store: New value: 42
Atomics.exchange()
// Shared memory setup const sharedBuffer = new SharedArrayBuffer(4); const sharedArray = new Int32Array(sharedBuffer); // Atomics.exchange() const originalExchangeValue = Atomics.exchange(sharedArray, 0, 99); console.log(`Atomics.exchange: Original value: ${originalExchangeValue}, New value: ${sharedArray[0]}`);
Output
Atomics.exchange: Original value: 42, New value: 99
Atomics.compareExchange()
// Shared memory setup const sharedBuffer = new SharedArrayBuffer(4); const sharedArray = new Int32Array(sharedBuffer); // Atomics.compareExchange() const expectedValue = 99; const newValue = 55; const successfulCompareExchange = Atomics.compareExchange(sharedArray, 0, expectedValue, newValue); console.log(`Atomics.compareExchange: Operation was${successfulCompareExchange ? ' ' : ' not '}successful. New value: ${sharedArray[0]}`);
Output
Atomics.compareExchange: Operation was successful. New value: 55
Atomics.wait()
// Shared memory setup const sharedBuffer = new SharedArrayBuffer(4); const sharedArray = new Int32Array(sharedBuffer); // Atomics.wait() const valueToWaitFor = 55; Atomics.store(sharedArray, 0, valueToWaitFor); setTimeout(() => { Atomics.notify(sharedArray, 0); }, 2000); const waitResult = Atomics.wait(sharedArray, 0, valueToWaitFor, 5000); console.log(`Atomics.wait: Wait result: ${waitResult}`);
Output
Atomics.wait: Wait result: timed-out
Example 2: Real-World Use Case - Synchronized Counter
In this real-world scenario, we employ the Atomics object to construct a synchronized counter; multiple threads increment this counter through the use of the Atomics.add() operation, thus guaranteeing atomicity in our update process. The functionality and necessity for effective thread coordination become evident with such an application: it offers practical data management solutions within a multi-threaded environment.
const sharedBuffer = new SharedArrayBuffer(4); const sharedArray = new Int32Array(sharedBuffer); // Synchronized counter function incrementCounter() { const incrementValue = 1; const originalValue = Atomics.add(sharedArray, 0, incrementValue); console.log(`Incremented counter by ${incrementValue}. New value: ${sharedArray[0]}`); } // Multiple threads incrementing the counter setInterval(() => { incrementCounter(); }, 1000); // Simulate other activities in the main thread setInterval(() => { console.log('Main thread doing other work.'); }, 3000);
Output
Incremented counter by 1. New value: 1 Incremented counter by 1. New value: 2 Main thread doing other work. Incremented counter by 1. New value: 3 Incremented counter by 1. New value: 4 Incremented counter by 1. New value: 5 Main thread doing other work. Incremented counter by 1. New value: 6 Incremented counter by 1. New value: 7 Incremented counter by 1. New value: 8 Main thread doing other work. ...