Skip to content

Commit b043372

Browse files
thread lock (examplehub#181)
1 parent f9667cf commit b043372

File tree

9 files changed

+273
-34
lines changed

9 files changed

+273
-34
lines changed

src/main/java/com/examplehub/basics/thread/DeadLockExample.java

Lines changed: 28 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,42 @@
11
package com.examplehub.basics.thread;
22

33
public class DeadLockExample {
4-
public Object resourceA = new Object();
5-
public Object resourceB = new Object();
4+
public final Object resourceA = new Object();
5+
public final Object resourceB = new Object();
66

77
public static void main(String[] args) {
88
DeadLockExample deadLockExample = new DeadLockExample();
99
Runnable runnableA =
10-
new Runnable() {
11-
@Override
12-
public void run() {
13-
synchronized (deadLockExample.resourceA) {
14-
System.out.println(Thread.currentThread().getName() + "get resourceA");
15-
try {
16-
Thread.sleep(1000);
17-
} catch (InterruptedException e) {
18-
e.printStackTrace();
19-
}
20-
System.out.println(Thread.currentThread().getName() + " is trying to get resourceB");
21-
synchronized (deadLockExample.resourceB) {
22-
System.out.println(Thread.currentThread().getName() + "get resourceB");
10+
() -> {
11+
synchronized (deadLockExample.resourceA) {
12+
System.out.println(Thread.currentThread().getName() + "get resourceA");
13+
try {
14+
Thread.sleep(1000);
15+
} catch (InterruptedException e) {
16+
e.printStackTrace();
17+
}
18+
System.out.println(Thread.currentThread().getName() + " is trying to get resourceB");
19+
synchronized (deadLockExample.resourceB) {
20+
System.out.println(Thread.currentThread().getName() + "get resourceB");
21+
}
2322
}
24-
}
25-
}
26-
};
23+
};
2724

2825
Runnable runnableB =
29-
new Runnable() {
30-
@Override
31-
public void run() {
32-
synchronized (deadLockExample.resourceB) {
33-
System.out.println(Thread.currentThread().getName() + "get resourceB");
34-
try {
35-
Thread.sleep(1000);
36-
} catch (InterruptedException e) {
37-
e.printStackTrace();
38-
}
39-
System.out.println(Thread.currentThread().getName() + " is trying to get resourceA");
40-
synchronized (deadLockExample.resourceA) {
41-
System.out.println(Thread.currentThread().getName() + "get resourceA");
26+
() -> {
27+
synchronized (deadLockExample.resourceB) {
28+
System.out.println(Thread.currentThread().getName() + "get resourceB");
29+
try {
30+
Thread.sleep(1000);
31+
} catch (InterruptedException e) {
32+
e.printStackTrace();
33+
}
34+
System.out.println(Thread.currentThread().getName() + " is trying to get resourceA");
35+
synchronized (deadLockExample.resourceA) {
36+
System.out.println(Thread.currentThread().getName() + "get resourceA");
37+
}
4238
}
43-
}
44-
}
45-
};
39+
};
4640

4741
new Thread(runnableA).start();
4842
new Thread(runnableB).start();
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package com.examplehub.basics.thread;
2+
3+
public class ReadWriteLockExample {
4+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package com.examplehub.basics.thread;
2+
3+
public class ReentrantLockConditionExample {
4+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package com.examplehub.basics.thread;
2+
3+
public class ReentrantLockExample {
4+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package com.examplehub.basics.thread;
2+
3+
public class WaitNotifyExample {
4+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package com.examplehub.basics.thread;
2+
3+
import org.junit.jupiter.api.Test;
4+
5+
import java.util.Arrays;
6+
import java.util.concurrent.locks.Lock;
7+
import java.util.concurrent.locks.ReadWriteLock;
8+
import java.util.concurrent.locks.ReentrantReadWriteLock;
9+
10+
import static org.junit.jupiter.api.Assertions.*;
11+
12+
class ReadWriteLockExampleTest {
13+
static class Counter {
14+
private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
15+
private final Lock rLock = readWriteLock.readLock();
16+
private final Lock wLock = readWriteLock.writeLock();
17+
18+
private final int[] counts = new int[10];
19+
20+
public void inc(int index) {
21+
wLock.lock();
22+
try {
23+
counts[index] += 1;
24+
}finally {
25+
wLock.unlock();
26+
}
27+
}
28+
29+
public int[] get() {
30+
rLock.lock();
31+
try {
32+
return Arrays.copyOf(counts, counts.length);
33+
}finally {
34+
rLock.unlock();
35+
}
36+
}
37+
}
38+
@Test
39+
void test() throws InterruptedException {
40+
Counter counter = new Counter();
41+
for (int i = 0; i < 10; i++) {
42+
int finalI = i;
43+
new Thread(()->{
44+
counter.inc(finalI);
45+
System.out.println(Arrays.toString(counter.get()));
46+
}).start();
47+
}
48+
Thread.sleep(100);
49+
assertEquals("[1, 1, 1, 1, 1, 1, 1, 1, 1, 1]", Arrays.toString(counter.get()));
50+
}
51+
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
package com.examplehub.basics.thread;
2+
3+
import org.junit.jupiter.api.Test;
4+
5+
import java.util.ArrayList;
6+
import java.util.LinkedList;
7+
import java.util.Queue;
8+
import java.util.concurrent.locks.Condition;
9+
import java.util.concurrent.locks.ReentrantLock;
10+
11+
class ReentrantLockConditionExampleTest {
12+
static class TaskQueue {
13+
Queue<String> queue = new LinkedList<>();
14+
ReentrantLock lock = new ReentrantLock();
15+
Condition condition = lock.newCondition();
16+
public void addTask(String task) {
17+
lock.lock();
18+
try {
19+
queue.add(task);
20+
condition.signalAll();
21+
}finally {
22+
lock.unlock();
23+
}
24+
}
25+
26+
public String getTask() throws InterruptedException {
27+
lock.lock();
28+
try {
29+
while (queue.isEmpty()) {
30+
condition.await();
31+
}
32+
return queue.remove();
33+
}finally {
34+
lock.unlock();
35+
}
36+
}
37+
}
38+
@Test
39+
void test() throws InterruptedException {
40+
var tasks = new TaskQueue();
41+
var threads = new ArrayList<Thread>();
42+
for (int i = 0; i < 5; i++) {
43+
Thread thread = new Thread(()->{
44+
while (true) {
45+
try {
46+
String task = tasks.getTask();
47+
System.out.println("execute: " + task);
48+
} catch (InterruptedException e) {
49+
System.out.println("thread " + Thread.currentThread().getName() + " interrupted" );
50+
return;
51+
}
52+
}
53+
});
54+
thread.start();
55+
threads.add(thread);
56+
}
57+
var addThread = new Thread(()->{
58+
for (int i = 0; i < 10; ++i) {
59+
String task = "task - " + Math.random();
60+
System.out.println("added: " + task);
61+
tasks.addTask(task);
62+
try {
63+
Thread.sleep(100);
64+
} catch (InterruptedException e) {
65+
e.printStackTrace();
66+
}
67+
}
68+
});
69+
addThread.start();
70+
addThread.join();
71+
Thread.sleep(100);
72+
for (var thread : threads) {
73+
thread.interrupt();
74+
}
75+
}
76+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package com.examplehub.basics.thread;
2+
3+
import org.junit.jupiter.api.Test;
4+
5+
import java.util.concurrent.locks.Lock;
6+
import java.util.concurrent.locks.ReentrantLock;
7+
8+
import static org.junit.jupiter.api.Assertions.*;
9+
10+
class ReentrantLockExampleTest {
11+
static class Counter {
12+
private final Lock lock = new ReentrantLock();
13+
private int count;
14+
public void add(int step) {
15+
lock.lock();
16+
try {
17+
count += step;
18+
}finally {
19+
lock.unlock();
20+
}
21+
}
22+
23+
public int getCount() {
24+
return count;
25+
}
26+
}
27+
@Test
28+
void test() throws InterruptedException {
29+
Counter counter = new Counter();
30+
for (int i = 0; i < 10; i++) {
31+
new Thread(()->{
32+
counter.add(1);
33+
}).start();
34+
35+
}
36+
Thread.sleep(100);
37+
assertEquals(10, counter.getCount());
38+
}
39+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package com.examplehub.basics.thread;
2+
3+
import org.junit.jupiter.api.Test;
4+
5+
import java.util.ArrayList;
6+
import java.util.LinkedList;
7+
import java.util.Queue;
8+
9+
class WaitNotifyExampleTest {
10+
static class TaskQueue {
11+
Queue<String> queue = new LinkedList<>();
12+
13+
public synchronized void addTask(String task) {
14+
queue.add(task);
15+
this.notifyAll();
16+
}
17+
18+
public synchronized String getTask() throws InterruptedException {
19+
while (queue.isEmpty()) {
20+
this.wait();
21+
}
22+
return queue.remove();
23+
}
24+
}
25+
@Test
26+
void test() throws InterruptedException {
27+
var tasks = new TaskQueue();
28+
var threads = new ArrayList<Thread>();
29+
for (int i = 0; i < 5; i++) {
30+
Thread thread = new Thread(()->{
31+
while (true) {
32+
try {
33+
String task = tasks.getTask();
34+
System.out.println("execute: " + task);
35+
} catch (InterruptedException e) {
36+
System.out.println("thread " + Thread.currentThread().getName() + " interrupted" );
37+
return;
38+
}
39+
}
40+
});
41+
thread.start();
42+
threads.add(thread);
43+
}
44+
var addThread = new Thread(()->{
45+
for (int i = 0; i < 10; ++i) {
46+
String task = "task - " + Math.random();
47+
System.out.println("added: " + task);
48+
tasks.addTask(task);
49+
try {
50+
Thread.sleep(100);
51+
} catch (InterruptedException e) {
52+
e.printStackTrace();
53+
}
54+
}
55+
});
56+
addThread.start();
57+
addThread.join();
58+
Thread.sleep(100);
59+
for (var thread : threads) {
60+
thread.interrupt();
61+
}
62+
}
63+
}

0 commit comments

Comments
 (0)