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 dictionary = 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)


Cao Trong Hien

0 Responses to "Một ví dụ về ReadWriteLock"

Đăng nhận xét