or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

atomic-arrays.mdatomic-operations.mdindex.mdlocks.mdthread-parking.mdtracing.md

atomic-arrays.mddocs/

0

# Atomic Arrays

1

2

Array-based atomic data structures for managing collections of atomic values with indexed access patterns.

3

4

## Capabilities

5

6

### Atomic Reference Array

7

8

Creates arrays of atomic references initialized with null values.

9

10

```kotlin { .api }

11

/**

12

* Creates array of AtomicRef<T> of specified size, where each element is initialized with null value

13

*/

14

fun <T> atomicArrayOfNulls(size: Int): AtomicArray<T?>

15

16

class AtomicArray<T> {

17

/** Array size property */

18

val size: Int

19

20

/** Get AtomicRef<T?> at index */

21

operator fun get(index: Int): AtomicRef<T?>

22

}

23

```

24

25

**Usage Examples:**

26

27

```kotlin

28

import kotlinx.atomicfu.*

29

30

class ConcurrentCache<T> {

31

private val cache = atomicArrayOfNulls<T>(100)

32

33

fun put(index: Int, value: T) {

34

if (index in 0 until cache.size) {

35

cache[index].value = value

36

}

37

}

38

39

fun get(index: Int): T? {

40

return if (index in 0 until cache.size) {

41

cache[index].value

42

} else null

43

}

44

45

fun compareAndSet(index: Int, expected: T?, newValue: T?): Boolean {

46

return if (index in 0 until cache.size) {

47

cache[index].compareAndSet(expected, newValue)

48

} else false

49

}

50

51

fun clear() {

52

for (i in 0 until cache.size) {

53

cache[i].value = null

54

}

55

}

56

}

57

```

58

59

### Atomic Integer Array

60

61

Creates arrays of atomic integers initialized with zero values.

62

63

```kotlin { .api }

64

/**

65

* Creates a new array of AtomicInt values of the specified size, where each element is initialized with 0

66

*/

67

class AtomicIntArray(size: Int) {

68

/** Array size property */

69

val size: Int

70

71

/** Get AtomicInt at index */

72

operator fun get(index: Int): AtomicInt

73

}

74

```

75

76

**Usage Examples:**

77

78

```kotlin

79

import kotlinx.atomicfu.*

80

81

class ConcurrentCounters {

82

private val counters = AtomicIntArray(10)

83

84

fun increment(index: Int): Int {

85

return if (index in 0 until counters.size) {

86

counters[index].incrementAndGet()

87

} else 0

88

}

89

90

fun add(index: Int, delta: Int): Int {

91

return if (index in 0 until counters.size) {

92

counters[index].addAndGet(delta)

93

} else 0

94

}

95

96

fun get(index: Int): Int {

97

return if (index in 0 until counters.size) {

98

counters[index].value

99

} else 0

100

}

101

102

fun reset(index: Int) {

103

if (index in 0 until counters.size) {

104

counters[index].value = 0

105

}

106

}

107

108

fun getTotalCount(): Int {

109

var total = 0

110

for (i in 0 until counters.size) {

111

total += counters[i].value

112

}

113

return total

114

}

115

}

116

```

117

118

### Atomic Long Array

119

120

Creates arrays of atomic longs initialized with zero values.

121

122

```kotlin { .api }

123

/**

124

* Creates a new array of AtomicLong values of the specified size, where each element is initialized with 0L

125

*/

126

class AtomicLongArray(size: Int) {

127

/** Array size property */

128

val size: Int

129

130

/** Get AtomicLong at index */

131

operator fun get(index: Int): AtomicLong

132

}

133

```

134

135

**Usage Examples:**

136

137

```kotlin

138

import kotlinx.atomicfu.*

139

140

class MetricsCollector {

141

private val metrics = AtomicLongArray(50)

142

143

fun recordMetric(metricId: Int, value: Long) {

144

if (metricId in 0 until metrics.size) {

145

metrics[metricId].addAndGet(value)

146

}

147

}

148

149

fun incrementMetric(metricId: Int): Long {

150

return if (metricId in 0 until metrics.size) {

151

metrics[metricId].incrementAndGet()

152

} else 0L

153

}

154

155

fun getMetric(metricId: Int): Long {

156

return if (metricId in 0 until metrics.size) {

157

metrics[metricId].value

158

} else 0L

159

}

160

161

fun resetMetric(metricId: Int) {

162

if (metricId in 0 until metrics.size) {

163

metrics[metricId].value = 0L

164

}

165

}

166

167

fun getSnapshot(): LongArray {

168

val snapshot = LongArray(metrics.size)

169

for (i in 0 until metrics.size) {

170

snapshot[i] = metrics[i].value

171

}

172

return snapshot

173

}

174

}

175

```

176

177

### Atomic Boolean Array

178

179

Creates arrays of atomic booleans initialized with false values.

180

181

```kotlin { .api }

182

/**

183

* Creates a new array of AtomicBoolean values of the specified size, where each element is initialized with false

184

*/

185

class AtomicBooleanArray(size: Int) {

186

/** Array size property */

187

val size: Int

188

189

/** Get AtomicBoolean at index */

190

operator fun get(index: Int): AtomicBoolean

191

}

192

```

193

194

**Usage Examples:**

195

196

```kotlin

197

import kotlinx.atomicfu.*

198

199

class ConcurrentFlags {

200

private val flags = AtomicBooleanArray(32)

201

202

fun setFlag(index: Int): Boolean {

203

return if (index in 0 until flags.size) {

204

flags[index].getAndSet(true)

205

} else false

206

}

207

208

fun clearFlag(index: Int): Boolean {

209

return if (index in 0 until flags.size) {

210

flags[index].getAndSet(false)

211

} else false

212

}

213

214

fun toggleFlag(index: Int): Boolean {

215

if (index in 0 until flags.size) {

216

val flag = flags[index]

217

while (true) {

218

val current = flag.value

219

if (flag.compareAndSet(current, !current)) {

220

return !current

221

}

222

}

223

}

224

return false

225

}

226

227

fun isSet(index: Int): Boolean {

228

return if (index in 0 until flags.size) {

229

flags[index].value

230

} else false

231

}

232

233

fun countSetFlags(): Int {

234

var count = 0

235

for (i in 0 until flags.size) {

236

if (flags[i].value) count++

237

}

238

return count

239

}

240

241

fun allSet(): Boolean {

242

for (i in 0 until flags.size) {

243

if (!flags[i].value) return false

244

}

245

return true

246

}

247

248

fun anySet(): Boolean {

249

for (i in 0 until flags.size) {

250

if (flags[i].value) return true

251

}

252

return false

253

}

254

}

255

```

256

257

## Advanced Usage Patterns

258

259

### Lock-Free Data Structures

260

261

Atomic arrays are commonly used to build lock-free data structures:

262

263

```kotlin

264

import kotlinx.atomicfu.*

265

266

class LockFreeQueue<T>(capacity: Int) {

267

private val buffer = atomicArrayOfNulls<T>(capacity)

268

private val head = atomic(0)

269

private val tail = atomic(0)

270

271

fun offer(item: T): Boolean {

272

while (true) {

273

val currentTail = tail.value

274

val nextTail = (currentTail + 1) % buffer.size

275

276

if (nextTail == head.value) {

277

// Queue is full

278

return false

279

}

280

281

if (buffer[currentTail].compareAndSet(null, item)) {

282

tail.compareAndSet(currentTail, nextTail)

283

return true

284

}

285

}

286

}

287

288

fun poll(): T? {

289

while (true) {

290

val currentHead = head.value

291

val item = buffer[currentHead].value

292

293

if (item == null) {

294

// Queue is empty

295

return null

296

}

297

298

if (buffer[currentHead].compareAndSet(item, null)) {

299

head.compareAndSet(currentHead, (currentHead + 1) % buffer.size)

300

return item

301

}

302

}

303

}

304

}

305

```

306

307

### Parallel Processing with Work Distribution

308

309

```kotlin

310

import kotlinx.atomicfu.*

311

312

class WorkDistributor<T>(private val tasks: List<T>) {

313

private val processed = AtomicBooleanArray(tasks.size)

314

private val results = atomicArrayOfNulls<String>(tasks.size)

315

private val nextIndex = atomic(0)

316

317

fun getNextTask(): Pair<Int, T>? {

318

while (true) {

319

val index = nextIndex.value

320

if (index >= tasks.size) return null

321

322

if (nextIndex.compareAndSet(index, index + 1)) {

323

return index to tasks[index]

324

}

325

}

326

}

327

328

fun completeTask(index: Int, result: String) {

329

results[index].value = result

330

processed[index].value = true

331

}

332

333

fun isComplete(): Boolean {

334

for (i in 0 until processed.size) {

335

if (!processed[i].value) return false

336

}

337

return true

338

}

339

340

fun getResults(): List<String?> {

341

return (0 until results.size).map { results[it].value }

342

}

343

}

344

```

345

346

## Implementation Notes

347

348

### Performance Characteristics

349

350

- Each element in atomic arrays is a separate atomic variable

351

- Index access is O(1) but involves atomic operations

352

- Memory overhead: each element requires atomic field updater setup

353

- Best suited for scenarios with known, fixed-size collections

354

355

### Thread Safety

356

357

- All operations on individual array elements are atomic

358

- Array size is immutable once created

359

- Concurrent access to different indices is fully thread-safe

360

- Operations on the same index are serialized through atomic operations