В книге The Art of Multiprocessor Proggramming (стр. 183-187) дается реализация Readers–Writers Locks:
public interface ReadWriteLock {
Lock readLock();
Lock writeLock();
}
1 public class SimpleReadWriteLock implements ReadWriteLock {
2 int readers;
3 boolean writer;
4 Lock lock;
5 Condition condition;
6 Lock readLock, writeLock;
7 public SimpleReadWriteLock() {
8 writer = false;
9 readers = 0;
10 lock = new ReentrantLock();
11 readLock = new ReadLock();
12 writeLock = new WriteLock();
13 condition = lock.newCondition();
14 }
15 public Lock readLock() {
16 return readLock;
17 }
18 public Lock writeLock() {
19 return writeLock;
20 }
//ReadLock inner class of SimpleReadWriteLock
21 class ReadLock implements Lock {
22 public void lock() {
23 lock.lock();
24 try {
25 while (writer) {
26 condition.await();
27 }
28 readers++;
29 } finally {
30 lock.unlock();
31 }
32 }
33 public void unlock() {
34 lock.lock();
35 try {
36 readers--;
37 if (readers == 0)
38 condition.signalAll();
39 } finally {
40 lock.unlock();
41 }
42 }
43 }
44 protected class WriteLock implements Lock {
45 public void lock() {
46 lock.lock();
47 try {
48 while (readers > 0) {
49 condition.await();
50 }
51 writer = true;
52 } finally {
53 lock.unlock();
54 }
55 }
56 public void unlock() {
57 writer = false;
58 condition.signalAll();
59 }
60 }
61 }
У этого кода есть недостаток. Если потоков чтения множества, то writer блокируется и ждет, пока чтение не прекратится. Мне показалось, что если я поменяю строку 51 местами с блоком while (стр. 48),
то эта проблема исчезнет, т.е. как только writer лочит lock, сразу устанливает флаг, все последующие readers будут ожидать.
Первый вопрос. Можете сказать, корректно это или нет? В книге, в разделе 8.3.2 Fair Readers–Writers Lock, дается решение этой проблемы несколько иное :
1 public class FifoReadWriteLock implements ReadWriteLock {
2 int readAcquires, readReleases;
3 boolean writer;
4 Lock lock;
5 Condition condition;
6 Lock readLock, writeLock;
7 public FifoReadWriteLock() {
8 readAcquires = readReleases = 0;
9 writer = false;
10 lock = new ReentrantLock();
11 condition = lock.newCondition();
12 readLock = new ReadLock();
13 writeLock = new WriteLock();
14 }
15 public Lock readLock() {
16 return readLock;
17 }
18 public Lock writeLock() {
19 return writeLock;
20 }
21 ...
22 }
23 private class ReadLock implements Lock {
24 public void lock() {
25 lock.lock();
26 try {
27 readAcquires++;
28 while (writer) {
29 condition.await();
30 }
31 } finally {
32 lock.unlock();
33 }
34 }
35 public void unlock() {
36 lock.lock();
37 try {
38 readReleases++;
39 if (readAcquires == readReleases)
40 condition.signalAll();
41 } finally {
42 lock.unlock();
43 }
44 }
45 }
46 private class WriteLock implements Lock {
47 public void lock() {
48 lock.lock();
49 try {
50 while (readAcquires != readReleases)
51 condition.await();
52 writer = true;
53 } finally {
54 lock.unlock();
55 }
56 }
57 public void unlock() {
58 writer = false;
59 }
60 }
61 }
Здесь якобы:
shows one way to give writers priority.. Только я не вижу этого.
Во первых, что я вижу, поправьте, плииз, если ошибаюсь (
второй вопрос):
Writer точно также блокируется, пока readAcquires != readReleases, и ждет момента пока не выполнется условие readAcquires == readReleases. Не понимаю, почему тут пишут:
"This class ensures that once a writer calls the write lock’s lock()
method, then no more readers will be able to acquire the read lock until the writer
has acquired and released the write lock. Eventually, the readers holding the read
lock will drain out without letting any more readers in, and the writer will acquire
the write lock."
И еще
третий вопрос, в строке 58, writer выставляет флаг writer = false, но следом не вызывает condition.signalAll(), это похоже опечатка? Ведь ридеры уже ожидающие writer никогда не выполнятся.
Здравствуйте, Аноним, Вы писали:
А>В книге The Art of Multiprocessor Proggramming (стр. 183-187) дается реализация Readers–Writers Locks:
Вам это для чего? Для повышения своего уровня? Читайте лучше и разбирайте код из java.util.concurrent, а то в этих книгах действительно могут быть ошибки. Зайдите на
http://g.oswego.edu/dl/concurrency-interest/, там много чего, и статьи, и документация, и форумы.