Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit db4e6ec

Browse files
test lock manager depends on tasks number
1 parent 37fa337 commit db4e6ec

File tree

2 files changed

+162
-0
lines changed

2 files changed

+162
-0
lines changed
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package thread.lock;
2+
3+
import java.util.Objects;
4+
import java.util.concurrent.locks.Lock;
5+
import java.util.concurrent.locks.ReentrantReadWriteLock;
6+
7+
/**
8+
* Handle ReentrantReadWriteLocks
9+
*
10+
* For example, Suppose we receive sequential numbers with 3 times and want to lock depends on number.
11+
* we received number 1 and 2 and do task with multiple thread respectively like below.
12+
*
13+
* Thread1 : number1 / Thread2 : number1 / Thread3: number1
14+
* Thread4 : number2 / Thread5 : number2 / Thread6: number2
15+
*
16+
* If we lock commonly, Thread2~ Thread6 have to wait completion of Thread1.
17+
*
18+
* So depends on task`s number, we can locks multiple threads.
19+
*
20+
* @author zacconding
21+
* @Date 2019年01月09日
22+
* @GitHub : https://github.com/zacscoding
23+
*/
24+
public class LockManager {
25+
26+
private ReentrantReadWriteLock[] locks;
27+
28+
public LockManager() {
29+
this(5);
30+
}
31+
32+
public LockManager(int concurrency) {
33+
if (concurrency < 1) {
34+
throw new RuntimeException("Concurrency must be lager than 0");
35+
}
36+
37+
locks = new ReentrantReadWriteLock[concurrency];
38+
for (int i = 0; i < concurrency; i++) {
39+
locks[i] = new ReentrantReadWriteLock();
40+
}
41+
}
42+
43+
public Lock readLock(Object taskIdentifier) {
44+
return locks[getIndex(taskIdentifier)].readLock();
45+
}
46+
47+
public Lock writeLock(Object taskIdentifier) {
48+
return locks[getIndex(taskIdentifier)].writeLock();
49+
}
50+
51+
private int getIndex(Object taskIdentifier) {
52+
Objects.requireNonNull(taskIdentifier, "taskIdentifier must be not null");
53+
return Math.abs(taskIdentifier.hashCode() % locks.length);
54+
}
55+
}
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
package thread.lock;
2+
3+
import java.util.concurrent.TimeUnit;
4+
import org.junit.Test;
5+
6+
/**
7+
* @author zacconding
8+
* @Date 2019年01月09日
9+
* @GitHub : https://github.com/zacscoding
10+
*/
11+
public class LockManagerTest {
12+
13+
@Test
14+
public void taskWithIds() throws InterruptedException {
15+
final LockManager lockManager = new LockManager(3);
16+
Thread t11 = new Thread(new Task(lockManager, 1, 0, 3));
17+
Thread t12 = new Thread(new Task(lockManager, 1, 0, 3));
18+
Thread t13 = new Thread(new Task(lockManager, 1, 0, 3));
19+
20+
Thread t21 = new Thread(new Task(lockManager, 2, 0, 3));
21+
Thread t22 = new Thread(new Task(lockManager, 2, 0, 3));
22+
Thread t23 = new Thread(new Task(lockManager, 2, 0, 3));
23+
24+
t11.start();
25+
t12.start();
26+
t13.start();
27+
28+
t21.start();
29+
t22.start();
30+
t23.start();
31+
32+
t11.join();
33+
t12.join();
34+
t13.join();
35+
36+
t21.join();
37+
t22.join();
38+
t23.join();
39+
// Outputs
40+
// 2 working write task ... 0
41+
// 1 working write task ... 0
42+
// 1 working write task ... 1
43+
// 2 working write task ... 1
44+
// 1 working write task ... 2
45+
// 2 working write task ... 2
46+
// 1 working write task ... 0
47+
// 2 working write task ... 0
48+
// 1 working write task ... 1
49+
// 2 working write task ... 1
50+
// 1 working write task ... 2
51+
// 2 working write task ... 2
52+
// 1 working write task ... 0
53+
// 2 working write task ... 0
54+
// 1 working write task ... 1
55+
// 2 working write task ... 1
56+
// 1 working write task ... 2
57+
// 2 working write task ... 2
58+
}
59+
60+
public static class Task implements Runnable {
61+
62+
private LockManager lockManager;
63+
private Object taskIdentifier;
64+
private int readTask;
65+
private int writeTask;
66+
67+
public Task(LockManager lockManager, Object taskIdentifier, int readTask, int writeTask) {
68+
this.lockManager = lockManager;
69+
this.taskIdentifier = taskIdentifier;
70+
this.readTask = readTask;
71+
this.writeTask = writeTask;
72+
}
73+
74+
@Override
75+
public void run() {
76+
try {
77+
final int identifier = taskIdentifier.hashCode();
78+
79+
if (readTask > 0) {
80+
try {
81+
lockManager.readLock(identifier).lock();
82+
for (int i = 0; i < readTask; i++) {
83+
System.out.println(String.format("%s working read task ... %d", identifier, i));
84+
TimeUnit.SECONDS.sleep(1L);
85+
}
86+
} finally {
87+
lockManager.readLock(identifier).unlock();
88+
}
89+
}
90+
91+
if (writeTask > 0) {
92+
try {
93+
lockManager.writeLock(identifier).lock();
94+
for (int i = 0; i < writeTask; i++) {
95+
System.out.println(String.format("%s working write task ... %d", identifier, i));
96+
TimeUnit.SECONDS.sleep(1L);
97+
}
98+
} finally {
99+
lockManager.writeLock(identifier).unlock();
100+
}
101+
}
102+
} catch (Exception e) {
103+
e.printStackTrace();
104+
}
105+
}
106+
}
107+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /