or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

concurrency.mdconstant-value.mdcontracts.mdframework.mdindex-bounds.mdindex.mdnullness.mdoptional.mdresources.mdsignedness.mdstring-format.mdunits.md

concurrency.mddocs/

0

# Concurrency Annotations

1

2

Concurrency annotations provide thread safety analysis and lock-based synchronization checking. These annotations help prevent data races, deadlocks, and other concurrency-related errors by tracking lock states and thread safety properties.

3

4

## Capabilities

5

6

### Lock Protection Annotations

7

8

Annotations that specify which locks protect shared resources.

9

10

```java { .api }

11

/**

12

* Indicates that the annotated expression is protected by the specified locks

13

*/

14

@Documented

15

@Retention(RetentionPolicy.RUNTIME)

16

@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})

17

@SubtypeOf(GuardedByUnknown.class)

18

public @interface GuardedBy {

19

String[] value();

20

}

21

22

/**

23

* Indicates that the guard is satisfied (lock is held)

24

*/

25

@Documented

26

@Retention(RetentionPolicy.RUNTIME)

27

@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})

28

@SubtypeOf(GuardedBy.class)

29

public @interface GuardSatisfied {}

30

31

@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})

32

@SubtypeOf(GuardedBy.class)

33

public @interface GuardedByBottom {}

34

35

@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})

36

@DefaultQualifierInHierarchy

37

public @interface GuardedByUnknown {}

38

39

/**

40

* Polymorphic guard qualifier

41

*/

42

@Documented

43

@Retention(RetentionPolicy.RUNTIME)

44

@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})

45

@PolymorphicQualifier(GuardedByUnknown.class)

46

public @interface PolyGuardedBy {}

47

```

48

49

**Usage Examples:**

50

51

```java

52

import org.checkerframework.checker.lock.qual.*;

53

54

public class GuardedExample {

55

private final Object lock = new Object();

56

private @GuardedBy("lock") int counter = 0;

57

private @GuardedBy("this") String name;

58

59

public synchronized void setName(String newName) {

60

this.name = newName; // Safe - synchronized method holds "this" lock

61

}

62

63

public void increment() {

64

synchronized (lock) {

65

counter++; // Safe - lock is held

66

}

67

}

68

69

public int getCounter() {

70

synchronized (lock) {

71

return counter; // Safe - lock protects read access too

72

}

73

}

74

75

// Method that works with any guarded value

76

public @PolyGuardedBy int process(@PolyGuardedBy int value) {

77

return value * 2; // Preserves guard requirements

78

}

79

}

80

```

81

82

### Lock State Annotations

83

84

Annotations that track whether locks are currently held.

85

86

```java { .api }

87

/**

88

* Indicates that the specified lock is currently held

89

*/

90

@Documented

91

@Retention(RetentionPolicy.RUNTIME)

92

@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})

93

public @interface LockHeld {}

94

95

/**

96

* Indicates that the specified lock may or may not be held

97

*/

98

@Documented

99

@Retention(RetentionPolicy.RUNTIME)

100

@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})

101

public @interface LockPossiblyHeld {}

102

```

103

104

**Usage Examples:**

105

106

```java

107

import org.checkerframework.checker.lock.qual.*;

108

109

public class LockStateExample {

110

private final Object lock = new Object();

111

private @GuardedBy("lock") int value = 0;

112

113

@Holding("lock")

114

public void updateValueWhileHeld(int newValue) {

115

// This method requires that 'lock' is already held

116

this.value = newValue; // Safe - precondition ensures lock is held

117

}

118

119

public void safeUpdate(int newValue) {

120

synchronized (lock) {

121

updateValueWhileHeld(newValue); // Safe - lock is held here

122

}

123

}

124

}

125

```

126

127

### Method-Level Lock Annotations

128

129

Annotations that specify lock requirements and effects for methods.

130

131

```java { .api }

132

/**

133

* Method requires that the specified locks are held when called

134

*/

135

@Documented

136

@Retention(RetentionPolicy.RUNTIME)

137

@Target(ElementType.METHOD)

138

@InheritedAnnotation

139

public @interface Holding {

140

String[] value();

141

}

142

143

/**

144

* Method releases no locks during execution

145

*/

146

@Documented

147

@Retention(RetentionPolicy.RUNTIME)

148

@Target(ElementType.METHOD)

149

public @interface ReleasesNoLocks {}

150

151

/**

152

* Method may release locks during execution

153

*/

154

@Documented

155

@Retention(RetentionPolicy.RUNTIME)

156

@Target(ElementType.METHOD)

157

public @interface MayReleaseLocks {}

158

159

/**

160

* Method performs no locking operations

161

*/

162

@Documented

163

@Retention(RetentionPolicy.RUNTIME)

164

@Target(ElementType.METHOD)

165

public @interface LockingFree {}

166

```

167

168

**Usage Examples:**

169

170

```java

171

import org.checkerframework.checker.lock.qual.*;

172

173

public class MethodLockExample {

174

private final Object lock1 = new Object();

175

private final Object lock2 = new Object();

176

private @GuardedBy("lock1") int value1 = 0;

177

private @GuardedBy("lock2") int value2 = 0;

178

179

@Holding({"lock1", "lock2"})

180

public void transferValue() {

181

// Requires both locks to be held

182

int temp = value1;

183

value1 = value2;

184

value2 = temp;

185

}

186

187

@ReleasesNoLocks

188

public int computeSum() {

189

// Method promises not to release any locks

190

synchronized (lock1) {

191

synchronized (lock2) {

192

return value1 + value2; // Locks remain held throughout

193

}

194

}

195

}

196

197

@MayReleaseLocks

198

public void processWithCallback(Runnable callback) {

199

synchronized (lock1) {

200

callback.run(); // Callback might release locks

201

}

202

}

203

204

@LockingFree

205

public int pureComputation(int a, int b) {

206

// No locking operations performed

207

return a * b + 42;

208

}

209

210

public void safeTransfer() {

211

synchronized (lock1) {

212

synchronized (lock2) {

213

transferValue(); // Safe - both required locks are held

214

}

215

}

216

}

217

}

218

```

219

220

### Object Creation and Escape Analysis

221

222

Annotations for tracking object creation and preventing premature sharing.

223

224

```java { .api }

225

/**

226

* Indicates a newly created object that has not escaped the current thread

227

*/

228

@Documented

229

@Retention(RetentionPolicy.RUNTIME)

230

@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})

231

public @interface NewObject {}

232

```

233

234

**Usage Examples:**

235

236

```java

237

import org.checkerframework.checker.lock.qual.*;

238

239

public class ObjectCreationExample {

240

private final Object lock = new Object();

241

private @GuardedBy("lock") List<String> items = new ArrayList<>();

242

243

public @NewObject List<String> createList() {

244

// Return value is a new object, not yet shared

245

return new ArrayList<>();

246

}

247

248

public void addNewItems() {

249

@NewObject List<String> newItems = createList();

250

newItems.add("item1"); // Safe - object not yet shared

251

newItems.add("item2");

252

253

// Now share the object safely

254

synchronized (lock) {

255

items.addAll(newItems); // Safe - lock protects shared state

256

}

257

}

258

}

259

```

260

261

### Lock Contract Annotations

262

263

Annotations for specifying lock-related method contracts.

264

265

```java { .api }

266

/**

267

* Method postcondition: ensures the specified locks are held after method execution

268

*/

269

@Target(ElementType.METHOD)

270

@Retention(RetentionPolicy.RUNTIME)

271

@InheritedAnnotation

272

public @interface EnsuresLockHeld {

273

String[] value();

274

}

275

276

/**

277

* Conditional method postcondition: ensures locks are held if method returns specified result

278

*/

279

@Target(ElementType.METHOD)

280

@Retention(RetentionPolicy.RUNTIME)

281

@InheritedAnnotation

282

public @interface EnsuresLockHeldIf {

283

String[] expression();

284

boolean result();

285

}

286

```

287

288

**Usage Examples:**

289

290

```java

291

import org.checkerframework.checker.lock.qual.*;

292

293

public class LockContractExample {

294

private final ReentrantLock lock = new ReentrantLock();

295

private @GuardedBy("lock") String data;

296

297

@EnsuresLockHeld("lock")

298

public void acquireLock() {

299

lock.lock(); // Postcondition ensures lock is held

300

}

301

302

@EnsuresLockHeldIf(expression = "lock", result = true)

303

public boolean tryAcquireLock() {

304

return lock.tryLock(); // If returns true, lock is held

305

}

306

307

public void safeDataAccess() {

308

acquireLock();

309

try {

310

// Safe - postcondition ensures lock is held

311

data = "new value";

312

System.out.println(data);

313

} finally {

314

lock.unlock();

315

}

316

}

317

318

public void conditionalAccess() {

319

if (tryAcquireLock()) {

320

try {

321

// Safe - conditional postcondition ensures lock is held

322

data = "conditional value";

323

System.out.println(data);

324

} finally {

325

lock.unlock();

326

}

327

} else {

328

System.out.println("Could not acquire lock");

329

}

330

}

331

}

332

```

333

334

### Advanced Concurrency Patterns

335

336

Examples of complex concurrency patterns using the lock annotations.

337

338

**Producer-Consumer Pattern:**

339

340

```java

341

import org.checkerframework.checker.lock.qual.*;

342

import java.util.concurrent.BlockingQueue;

343

import java.util.concurrent.LinkedBlockingQueue;

344

345

public class ProducerConsumerExample {

346

private final Object stateLock = new Object();

347

private @GuardedBy("stateLock") boolean running = true;

348

private final BlockingQueue<String> queue = new LinkedBlockingQueue<>();

349

350

@Holding("stateLock")

351

private void checkRunning() {

352

if (!running) {

353

throw new IllegalStateException("System is stopped");

354

}

355

}

356

357

public void produce(String item) {

358

synchronized (stateLock) {

359

checkRunning(); // Safe - lock is held

360

}

361

362

try {

363

queue.put(item); // BlockingQueue is thread-safe

364

} catch (InterruptedException e) {

365

Thread.currentThread().interrupt();

366

}

367

}

368

369

public String consume() {

370

synchronized (stateLock) {

371

checkRunning(); // Safe - lock is held

372

}

373

374

try {

375

return queue.take(); // BlockingQueue is thread-safe

376

} catch (InterruptedException e) {

377

Thread.currentThread().interrupt();

378

return null;

379

}

380

}

381

382

public void stop() {

383

synchronized (stateLock) {

384

running = false; // Safe - lock protects shared state

385

}

386

}

387

}

388

```

389

390

**Reader-Writer Pattern:**

391

392

```java

393

import org.checkerframework.checker.lock.qual.*;

394

import java.util.concurrent.locks.ReadWriteLock;

395

import java.util.concurrent.locks.ReentrantReadWriteLock;

396

397

public class ReaderWriterExample {

398

private final ReadWriteLock rwLock = new ReentrantReadWriteLock();

399

private @GuardedBy("rwLock") String data = "initial";

400

401

@Holding("rwLock.readLock()")

402

public String readData() {

403

return data; // Safe - read lock protects access

404

}

405

406

@Holding("rwLock.writeLock()")

407

public void writeData(String newData) {

408

this.data = newData; // Safe - write lock protects access

409

}

410

411

public String safeRead() {

412

rwLock.readLock().lock();

413

try {

414

return readData(); // Safe - read lock is held

415

} finally {

416

rwLock.readLock().unlock();

417

}

418

}

419

420

public void safeWrite(String newData) {

421

rwLock.writeLock().lock();

422

try {

423

writeData(newData); // Safe - write lock is held

424

} finally {

425

rwLock.writeLock().unlock();

426

}

427

}

428

}

429

```