Một ví dụ về ReadWriteLock
Việc viết ứng dụng Java đa luồng là không đơn giản. Cần hết sức quan tâm bởi vì viết đồng bộ hóa không tốt có thể làm cho ứng dụng của các bạn rời rạc. Bộ JVM được dùng chung bởi mọi luồng. Nếu nhiều luồng cần sử dụng cùng đối tượng hay những biến tĩnh, sự truy nhập tới dữ liệu dùng cùng một luồng phải được quản lý cẩn thận. Từ phiên bản 1.5, những lớp tiện ích trong lập trình đồng bộ đã được thêm vô trong bộ JSDK.
Trong từ khóa synchronized được dùng để nhận một khóa riêng trên một đối tượng. Khi một luồng nhận một khóa trên một đối tượng để đọc hay viết, những luồng khác phải đợi cho đến khi khóa trên đối tượng đó thả ra. Với cách suy nghĩ có thể có nhiều luồng đọc một dữ liệu dùng chung và chỉ có một luồng viết được cập nhật dữ liệu trên nó. Không cần thiết khóa khi đọc dữ liệu dùng chung bởi vì nhiều thao tác đọc có thể thực hiện song song trừ khi có một thao tác viết.
Bài viết này là một ví dụ dùng interface ReadWriteLock được giới thiệu trong bộ Java 1.5 API. Và trong đó có đoạn viết:
A ReadWriteLock maintains a pair of associated locks, one for read-only operations and one for writing. The read lock may be held simultaneously by multiple reader threads, so long as there are no writers. The write lock is exclusive.
Writer.java Để cập nhật dữ liệu. Writer dùng WriteLock của ReadWriteLock để khoá truy cập đến dictionary.
01
package
deneme.readwritelock;
02
03
04
public class
Writer
extends
Thread{
05
private boolean
runForestRun =
true
;
06
private
Dictionary dictionary =
null
;
07
08
public
Writer(Dictionary d, String threadName) {
09
this
.dictionary = d;
10
this
.setName(threadName);
11
}
12
@Override
13
public void
run() {
14
while
(
this
.runForestRun) {
15
String [] keys = dictionary.getKeys();
16
for
(String key : keys) {
17
String newValue = getNewValueFromDatastore(key);
18
//updating dictionary with WRITE LOCK
19
dictionary.set(key, newValue);
20
}
21
22
//update every seconds
23
try
{
24
Thread.sleep(
1000
);
25
}
catch
(InterruptedException e) {
26
e.printStackTrace();
27
}
28
}
29
}
30
public void
stopWriter(){
31
this
.runForestRun =
false
;
32
this
.interrupt();
33
}
34
public
String getNewValueFromDatastore(String key){
35
//This part is not implemented. Out of scope of this artile
36
return
"newValue"
;
37
}
38
}
Reader.java Đọc dữ liệu.
01
package
deneme.readwritelock;
02
03
public class
Reader
extends
Thread{
04
05
private
Dictionary dictionary =
null
;
06
public
Reader(Dictionary d, String threadName) {
07
this
.dictionary = d;
08
this
.setName(threadName);
09
}
10
11
private boolean
runForestRun =
true
;
12
@Override
13
public void
run() {
14
while
(runForestRun) {
15
String [] keys = dictionary.getKeys();
16
for
(String key : keys) {
17
//reading from dictionary with READ LOCK
18
String value = dictionary.get(key);
19
20
//make what ever you want with the value.
21
System.out.println(key +
" : "
+ value);
22
}
23
24
//update every seconds
25
try
{
26
Thread.sleep(
1000
);
27
}
catch
(InterruptedException e) {
28
e.printStackTrace();
29
}
30
}
31
}
32
33
public void
stopReader(){
34
this
.runForestRun =
false
;
35
this
.interrupt();
36
}
37
}
Dictionary.java Quản lý truy cập đến dictionary. Đọc được quản lý bởi ReadLock và viết (cập nhật) được quản lý bởi WriteLock.
01
package
deneme.readwritelock;
02
03
import
java.util.HashMap;
04
import
java.util.concurrent.locks.Lock;
05
import
java.util.concurrent.locks.ReentrantReadWriteLock;
06
07
public class
Dictionary {
08
09
private final
ReentrantReadWriteLock readWriteLock =
10
new
ReentrantReadWriteLock();
11
12
private final
Lock read = readWriteLock.readLock();
13
14
private final
Lock write = readWriteLock.writeLock();
15
16
private
HashMap
new
HashMap
17
18
public void
set(String key, String value) {
19
write.lock();
20
try
{
21
dictionary.put(key, value);
22
}
finally
{
23
write.unlock();
24
}
25
}
26
27
public
String get(String key) {
28
read.lock();
29
try
{
30
return
dictionary.get(key);
31
}
finally
{
32
read.unlock();
33
}
34
}
35
36
public
String[] getKeys(){
37
read.lock();
38
try
{
39
String keys[] =
new
String[dictionary.size()];
40
return
dictionary.keySet().toArray(keys);
41
}
finally
{
42
read.unlock();
43
}
44
}
45
46
public static void
main(String[] args) {
47
Dictionary dictionary =
new
Dictionary();
48
dictionary.set(
"java"
,
"object oriented"
);
49
dictionary.set(
"linux"
,
"rulez"
);
50
Writer writer =
new
Writer(dictionary,
"Mr. Writer"
);
51
Reader reader1 =
new
Reader(dictionary ,
"Mrs Reader 1"
);
52
Reader reader2 =
new
Reader(dictionary ,
"Mrs Reader 2"
);
53
Reader reader3 =
new
Reader(dictionary ,
"Mrs Reader 3"
);
54
Reader reader4 =
new
Reader(dictionary ,
"Mrs Reader 4"
);
55
Reader reader5 =
new
Reader(dictionary ,
"Mrs Reader 5"
);
56
writer.start();
57
reader1.start();
58
reader2.start();
59
reader3.start();
60
reader4.start();
61
reader5.start();
62
}
63
64
}
Theo(ilkinbalkanay)
Đọc tiếp >>