-
Notifications
You must be signed in to change notification settings - Fork 319
/
Copy pathUsingIntrinsicLocks.java
87 lines (79 loc) · 2.59 KB
/
UsingIntrinsicLocks.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
package br.com.leonardoz.features.locks;
import java.util.concurrent.Executors;
/**
* Every Java object has an intrinsic lock (or a monitor lock) associated with
* it.
*
* Every Java object can be used as a lock.
*
* Intrinsic Locks are mutually exclusive, so one only thread can 'hold' the
* lock at time when it's using the synchronization mechanism.
*
* The lock is freed when the synchronized method/block ends.
*
* Synchronize serializes access for what is locked and guarantee memory
* visibility for the changes that happened inside the synchronized scope to all
* threads.
*
* Intrinsic locks are reentrant: if you are holding it, you can acquire it
* again, without deadlocking.
*/
public class UsingIntrinsicLocks {
private boolean state;
/**
* When used in method signature, synchronized use 'this' as a lock.
*
* Instead of 'this', other objects variables can be used
*/
public synchronized void mySynchronizedMethod() {
state = !state;
// Everything in this method can only be accessed by the thread who hold the
// lock.
System.out.println("My state is:" + state);
// Without sync: states have no order guarantee true, true, false, true...
// With sync: always true, false, true, false...
}
/**
* It's possible to lock only a block inside the method
*/
public void mySynchronizedBlock() {
/*
* Everything in this block can only be accessed by the thread who hold the
* lock. The message bellow will be printed before the message inside the
* synchronized block
*/
System.out.println("Who owns my lock: " + Thread.currentThread().getName());
synchronized (this) {
state = !state;
System.out.println("Who owns my lock after state changes: " + Thread.currentThread().getName());
System.out.println("State is: " + state);
System.out.println("====");
}
}
/**
* Already holds a lock when called
*/
public synchronized void reentrancy() {
System.out.println("Before acquiring again");
// Tries to hold it without releasing the lock
synchronized (this) {
System.out.println("I'm own it! " + Thread.currentThread().getName());
}
}
public static void main(String[] args) throws InterruptedException {
var executor = Executors.newCachedThreadPool();
var self = new UsingIntrinsicLocks();
for (int i = 0; i < 100; i++) {
executor.execute(() -> self.mySynchronizedMethod());
}
Thread.sleep(1000);
for (int i = 0; i < 10; i++) {
executor.execute(() -> self.mySynchronizedBlock());
}
Thread.sleep(1000);
for (int i = 0; i < 10; i++) {
executor.execute(() -> self.reentrancy());
}
executor.shutdown();
}
}