0
# Atomic Arrays
1
2
Arrays of atomic values for bulk operations and indexed atomic access patterns.
3
4
## Capabilities
5
6
### Array Factory Functions
7
8
Creates atomic arrays for different primitive and reference types.
9
10
```kotlin { .api }
11
/**
12
* Creates an atomic integer array of specified size
13
* @param size - Number of atomic integers in the array
14
* @returns AtomicIntArray instance with atomic integer elements
15
*/
16
class AtomicIntArray(size: Int)
17
18
/**
19
* Creates an atomic long array of specified size
20
* @param size - Number of atomic longs in the array
21
* @returns AtomicLongArray instance with atomic long elements
22
*/
23
class AtomicLongArray(size: Int)
24
25
/**
26
* Creates an atomic boolean array of specified size
27
* @param size - Number of atomic booleans in the array
28
* @returns AtomicBooleanArray instance with atomic boolean elements
29
*/
30
class AtomicBooleanArray(size: Int)
31
32
/**
33
* Creates an atomic reference array initialized with nulls
34
* @param size - Number of atomic references in the array
35
* @returns AtomicArray<T?> instance with atomic reference elements
36
*/
37
fun <T> atomicArrayOfNulls(size: Int): AtomicArray<T?>
38
```
39
40
**Usage Examples:**
41
42
```kotlin
43
import kotlinx.atomicfu.*
44
45
// Create atomic arrays
46
val counters = AtomicIntArray(10)
47
val flags = AtomicBooleanArray(5)
48
val nodes = atomicArrayOfNulls<Node>(20)
49
```
50
51
### AtomicIntArray Operations
52
53
Array of atomic integers with indexed access.
54
55
```kotlin { .api }
56
class AtomicIntArray(size: Int) {
57
/** Gets the atomic integer at the specified index */
58
operator fun get(index: Int): AtomicInt
59
60
/** Index-based access to atomic integer elements */
61
operator fun set(index: Int, value: AtomicInt): Unit
62
}
63
```
64
65
**Usage Examples:**
66
67
```kotlin
68
val counters = AtomicIntArray(10)
69
70
// Access elements
71
counters[0].value = 5
72
val oldValue = counters[1].getAndIncrement()
73
counters[2].compareAndSet(0, 42)
74
75
// Array operations with atomic elements
76
counters[3].update { it * 2 }
77
counters[4].loop { value ->
78
if (counters[4].compareAndSet(value, value + 1)) {
79
return@loop
80
}
81
}
82
83
// Bulk operations
84
for (i in 0 until 10) {
85
counters[i].incrementAndGet()
86
}
87
```
88
89
### AtomicLongArray Operations
90
91
Array of atomic longs with indexed access.
92
93
```kotlin { .api }
94
class AtomicLongArray(size: Int) {
95
/** Gets the atomic long at the specified index */
96
operator fun get(index: Int): AtomicLong
97
98
/** Index-based access to atomic long elements */
99
operator fun set(index: Int, value: AtomicLong): Unit
100
}
101
```
102
103
**Usage Examples:**
104
105
```kotlin
106
val timers = AtomicLongArray(5)
107
108
// Large number operations
109
timers[0].value = System.currentTimeMillis()
110
timers[1].addAndGet(1000000000L)
111
112
// Update with validation
113
timers[2].update { currentTime ->
114
if (currentTime > 0) currentTime + 1000 else System.currentTimeMillis()
115
}
116
```
117
118
### AtomicBooleanArray Operations
119
120
Array of atomic booleans with indexed access.
121
122
```kotlin { .api }
123
class AtomicBooleanArray(size: Int) {
124
/** Gets the atomic boolean at the specified index */
125
operator fun get(index: Int): AtomicBoolean
126
127
/** Index-based access to atomic boolean elements */
128
operator fun set(index: Int, value: AtomicBoolean): Unit
129
}
130
```
131
132
**Usage Examples:**
133
134
```kotlin
135
val statusFlags = AtomicBooleanArray(10)
136
137
// Flag operations
138
statusFlags[0].compareAndSet(false, true)
139
val wasEnabled = statusFlags[1].getAndSet(false)
140
141
// Bulk flag operations
142
for (i in 0 until 10) {
143
statusFlags[i].update { !it } // toggle all flags
144
}
145
146
// Conditional operations
147
statusFlags[2].loop { current ->
148
if (!current && statusFlags[2].compareAndSet(false, true)) {
149
return@loop // successfully acquired flag
150
}
151
}
152
```
153
154
### AtomicArray Operations
155
156
Generic array of atomic references with indexed access.
157
158
```kotlin { .api }
159
class AtomicArray<T>(size: Int) {
160
/** Gets the atomic reference at the specified index */
161
operator fun get(index: Int): AtomicRef<T>
162
163
/** Index-based access to atomic reference elements */
164
operator fun set(index: Int, value: AtomicRef<T>): Unit
165
}
166
```
167
168
**Usage Examples:**
169
170
```kotlin
171
data class Task(val id: Int, val name: String)
172
173
val tasks = atomicArrayOfNulls<Task>(10)
174
175
// Reference operations
176
tasks[0].value = Task(1, "First Task")
177
val oldTask = tasks[1].getAndSet(Task(2, "Second Task"))
178
179
// Lock-free data structure operations
180
fun addTask(index: Int, task: Task): Boolean {
181
return tasks[index].compareAndSet(null, task)
182
}
183
184
fun removeTask(index: Int): Task? {
185
return tasks[index].getAndSet(null)
186
}
187
188
// Atomic updates
189
tasks[2].update { currentTask ->
190
currentTask?.copy(name = "${currentTask.name} - Updated")
191
}
192
193
// Complex array operations
194
fun findAndUpdateTask(predicate: (Task?) -> Boolean, update: (Task?) -> Task?): Boolean {
195
for (i in 0 until 10) {
196
tasks[i].loop { current ->
197
if (predicate(current)) {
198
val newValue = update(current)
199
if (tasks[i].compareAndSet(current, newValue)) {
200
return true
201
}
202
} else {
203
return@loop
204
}
205
}
206
}
207
return false
208
}
209
```
210
211
### Array Access Patterns
212
213
Common patterns for working with atomic arrays.
214
215
**Usage Examples:**
216
217
```kotlin
218
// Pattern 1: Parallel counters
219
val workerCounters = AtomicIntArray(Runtime.getRuntime().availableProcessors())
220
221
fun incrementWorkerCounter(workerId: Int) {
222
workerCounters[workerId].incrementAndGet()
223
}
224
225
// Pattern 2: Lock-free ring buffer
226
class LockFreeRingBuffer<T>(capacity: Int) {
227
private val buffer = atomicArrayOfNulls<T>(capacity)
228
private val head = atomic(0)
229
private val tail = atomic(0)
230
231
fun offer(item: T): Boolean {
232
val currentTail = tail.value
233
val nextTail = (currentTail + 1) % buffer.size
234
235
return if (nextTail != head.value) {
236
buffer[currentTail].compareAndSet(null, item) &&
237
tail.compareAndSet(currentTail, nextTail)
238
} else {
239
false // buffer full
240
}
241
}
242
243
fun poll(): T? {
244
val currentHead = head.value
245
return if (currentHead != tail.value) {
246
val item = buffer[currentHead].getAndSet(null)
247
head.compareAndSet(currentHead, (currentHead + 1) % buffer.size)
248
item
249
} else {
250
null // buffer empty
251
}
252
}
253
}
254
255
// Pattern 3: Atomic bit set
256
class AtomicBitSet(size: Int) {
257
private val bits = AtomicBooleanArray(size)
258
259
fun set(index: Int): Boolean = bits[index].getAndSet(true)
260
fun clear(index: Int): Boolean = bits[index].getAndSet(false)
261
fun get(index: Int): Boolean = bits[index].value
262
263
fun setIf(index: Int, condition: Boolean): Boolean {
264
return if (condition) bits[index].compareAndSet(false, true) else false
265
}
266
}
267
```