参考package EDU.oswego.cs.dl.util.concurrent
1![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
public interface Sync
{
2
public void acquire();
3
public void release();
4
}
1![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
/**//**
2
* A simple Sempahore implementaion.
3
*
4
* @author sakis
5
*/
6![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
public class Semaphore implements Sync
{
7
private int value;
8![](/Images/OutliningIndicators/InBlock.gif)
9![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//**
10
* Sempahore(1) is a Mutex.
11
*/
12![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public Semaphore()
{
13
value = 1;
14
}
15![](/Images/OutliningIndicators/InBlock.gif)
16![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public Semaphore(int value)
{
17
this.value = value;
18
}
19![](/Images/OutliningIndicators/InBlock.gif)
20![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//**
21
* P(): waits until the semaphore's value is greater than zero( there are
22
* enough resources to use), then decrements it.
23
*/
24![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
synchronized public void acquire()
{
25![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
while (value <= 0)
{
26![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
try
{
27
wait();
28![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
} catch (InterruptedException e)
{
29
}
30
}
31
--value;
32
}
33![](/Images/OutliningIndicators/InBlock.gif)
34![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//**
35
* V(): increments the semaphore's value(release one resource), and wakes up
36
* threads waiting in P() if possible.
37
*/
38![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
synchronized public void release()
{
39
++value;
40
notify();
41
}
42
}
1![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
/**//**
2
* 读-写锁,读者和写者互斥,写者之间互斥。
3
* Standard usage:
4
* class X {
5
* ReadWriteLock rw;
6
* // ![](/Images/dot.gif)
7
* public void read() throws InterruptedException {
8
* rw.readLock().acquire();
9
* try {
10
* //
do the read
11
* }
12
* finally {
13
* rw.readlock().release()
14
* }
15
* }
16
*
17
* public void write() throws InterruptedException {
18
* rw.writeLock().acquire();
19
* try {
20
* //
do the write
21
* }
22
* finally {
23
* rw.writelock().release()
24
* }
25
* }
26
* }
27
* @see NoPreferenceReadWriteLock
28
* NoPreferenceReadWriteLockWithSemaphore
29
* WriterPreferenceReadWriteLock
30
*/
31![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
public interface ReadWriteLock
{
32
public Sync readLock();
33
public Sync writeLock();
34
}
第一种读写锁实现,使用java的管程,reader和writer优先级相同
1![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
/**//**
2
* WriteReadLock implementation, reader writer have same priority.
3
* @author sakis
4
*/
5![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
public class NoPreferenceReadWriteLock implements ReadWriteLock
{
6
private static int readCount = 0;
7
private static final int FREE = 0;
8
private static final int READING = 1;
9
private static final int WRITING = 2;
10
private int status = FREE;
11
private final ReadLock readLock = new ReadLock();
12
private final WriteLock writeLock = new WriteLock();
13![](/Images/OutliningIndicators/InBlock.gif)
14![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public Sync readLock()
{
15
return readLock;
16
}
17![](/Images/OutliningIndicators/InBlock.gif)
18![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public Sync writeLock()
{
19
return writeLock;
20
}
21![](/Images/OutliningIndicators/InBlock.gif)
22![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
private class ReadLock implements Sync
{
23![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public void acquire()
{
24
beforeRead();
25
}
26![](/Images/OutliningIndicators/InBlock.gif)
27![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public void release()
{
28
afterRead();
29
}
30
}
31![](/Images/OutliningIndicators/InBlock.gif)
32![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
private class WriteLock implements Sync
{
33![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public void acquire()
{
34
beforeWrite();
35
}
36![](/Images/OutliningIndicators/InBlock.gif)
37![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public void release()
{
38
afterWrite();
39
}
40
}
41![](/Images/OutliningIndicators/InBlock.gif)
42![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
private synchronized void beforeRead()
{
43![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
while (!canRead())
{
44![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
try
{
45
wait();
46![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
} catch (InterruptedException e)
{
47
}
48
}
49
// If I'm the first reader, mark the status as READING.
50
if (++readCount == 1)
51
setStatus(READING);
52
}
53![](/Images/OutliningIndicators/InBlock.gif)
54![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
private synchronized void afterRead()
{
55
// If I'm the last reader, mark the status as FREE.
56
// and wake up one writer who waits on the database.
57![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (--readCount == 0)
{
58
setStatus(FREE);
59
notify();
60
}
61
}
62![](/Images/OutliningIndicators/InBlock.gif)
63![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
private synchronized void beforeWrite()
{
64
// Wait until nobody is writing or reading the database.
65![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
while (!canWrite())
{
66![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
try
{
67
wait();
68![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
} catch (InterruptedException e)
{
69
}
70
}
71
// mark the status as WRITING.
72
setStatus(WRITING);
73
}
74![](/Images/OutliningIndicators/InBlock.gif)
75![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
private synchronized void afterWrite()
{
76
// After writing, mark the status as FREE.
77
// and wake up all readers who waits on the database.
78
setStatus(FREE);
79
notifyAll();
80
}
81![](/Images/OutliningIndicators/InBlock.gif)
82![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
private boolean canRead()
{
83
return status == FREE || status == READING;
84
}
85![](/Images/OutliningIndicators/InBlock.gif)
86![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
private boolean canWrite()
{
87
return status == FREE;
88
}
89![](/Images/OutliningIndicators/InBlock.gif)
90![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
private void setStatus(int status)
{
91
this.status = status;
92
}
93![](/Images/OutliningIndicators/InBlock.gif)
94
}
第二种读写锁实现,使用信号量,reader和writer优先级相同
1![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
/**//**
2
* WriteReadLock implementation using Semaphore,
3
* reader writer have same priority.
4
* @author sakis
5
*/
6![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
public class NoPreferenceReadWriteLockWithSemaphore implements ReadWriteLock
{
7
private static int readCount = 0;
8
private Semaphore rcMutex = new Semaphore();
9
private Semaphore dataMutex = new Semaphore();;
10
private final ReadLock readLock = new ReadLock();
11
private final WriteLock writeLock = new WriteLock();
12![](/Images/OutliningIndicators/InBlock.gif)
13![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public Sync readLock()
{
14
return readLock;
15
}
16![](/Images/OutliningIndicators/InBlock.gif)
17![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public Sync writeLock()
{
18
return writeLock;
19
}
20![](/Images/OutliningIndicators/InBlock.gif)
21![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
private class ReadLock implements Sync
{
22![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public void acquire()
{
23
beforeRead();
24
}
25![](/Images/OutliningIndicators/InBlock.gif)
26![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public void release()
{
27
afterRead();
28
}
29
}
30![](/Images/OutliningIndicators/InBlock.gif)
31![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
private class WriteLock implements Sync
{
32![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public void acquire()
{
33
beforeWrite();
34
}
35![](/Images/OutliningIndicators/InBlock.gif)
36![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public void release()
{
37
afterWrite();
38
}
39
}
40![](/Images/OutliningIndicators/InBlock.gif)
41![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
private synchronized void beforeRead()
{
42
rcMutex.acquire();
43
// If i'm the first reader, disallow writer
44
// to access the database by dataMutex.P();
45
if (++readCount == 1)
46
dataMutex.acquire();
47
rcMutex.release();
48
}
49![](/Images/OutliningIndicators/InBlock.gif)
50![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
private synchronized void afterRead()
{
51
rcMutex.acquire();
52
// If I'm the last reader, re-allow writer
53
// to access the database by dataMutex.V();
54
if (--readCount == 0)
55
dataMutex.release();
56
rcMutex.release();
57
}
58![](/Images/OutliningIndicators/InBlock.gif)
59![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
private synchronized void beforeWrite()
{
60
// disallow other readers,writers to access
61
// the database.
62
dataMutex.acquire();
63
}
64![](/Images/OutliningIndicators/InBlock.gif)
65![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
private synchronized void afterWrite()
{
66
dataMutex.release();
67
}
68
} 第三种读写锁实现,使用信号量,writer优先级高。
@see EDU.oswego.cs.dl.util.concurrent.WriterPreferenceReadWriteLock
1![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
/**//**
2
* WriteReadLock implementation, writer has higher priority.
3
*/
4![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
public class WriterPreferenceReadWriteLock implements ReadWriteLock
{
5![](/Images/OutliningIndicators/InBlock.gif)
6
private long waitingReaders = 0; // threads try to read
7
private long waitingWriters = 0; // threads try to write
8![](/Images/OutliningIndicators/InBlock.gif)
9
private long activeReaders = 0; // threads excuting read
10
private long activeWriters = 0; // threads excuting write, 0 or 1
11![](/Images/OutliningIndicators/InBlock.gif)
12
private final ReadLock readLock = new ReadLock();
13
private final WriteLock writeLock = new WriteLock();
14![](/Images/OutliningIndicators/InBlock.gif)
15![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//*
16
* @see mis0204.tao.concurrent.ReadWriteLock#readLock()
17
*/
18![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public Sync readLock()
{
19
return readLock;
20
}
21![](/Images/OutliningIndicators/InBlock.gif)
22![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//*
23
* @see mis0204.tao.concurrent.ReadWriteLock#writeLOck()
24
*/
25![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public Sync writeLock()
{
26
return writeLock;
27
}
28![](/Images/OutliningIndicators/InBlock.gif)
29![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
private class ReadLock implements Sync
{
30![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public void acquire()
{
31
beforeRead();
32
}
33![](/Images/OutliningIndicators/InBlock.gif)
34![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public void release()
{
35
afterRead();
36
}
37
}
38![](/Images/OutliningIndicators/InBlock.gif)
39![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
private class WriteLock implements Sync
{
40![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public void acquire()
{
41
beforeWrite();
42
}
43![](/Images/OutliningIndicators/InBlock.gif)
44![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public void release()
{
45
afterWrite();
46
}
47
}
48![](/Images/OutliningIndicators/InBlock.gif)
49![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
private synchronized void beforeRead()
{
50
++waitingReaders;
51![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
while (!canRead())
{
52![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
try
{
53
wait();
54![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
} catch (InterruptedException e)
{
55
--waitingReaders; // roll back state
56
e.printStackTrace();
57
}
58
}
59
--waitingReaders;
60
++activeReaders;
61
}
62![](/Images/OutliningIndicators/InBlock.gif)
63![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
private synchronized void afterRead()
{
64
--activeReaders;
65
notifyAll();
66
}
67![](/Images/OutliningIndicators/InBlock.gif)
68![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
private synchronized void beforeWrite()
{
69
++waitingWriters;
70![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
while (!canWrite())
{
71![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
try
{
72
wait();
73![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
} catch (InterruptedException e)
{
74
--waitingWriters; // roll back state
75
e.printStackTrace();
76
}
77
}
78
--waitingWriters;
79
++activeWriters;
80
}
81![](/Images/OutliningIndicators/InBlock.gif)
82![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
private synchronized void afterWrite()
{
83
--activeWriters;
84
notifyAll();
85
}
86![](/Images/OutliningIndicators/InBlock.gif)
87![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//**
88
* @return true if no writers are waiting/writing on the resource.
89
*/
90![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
private boolean canRead()
{
91
return waitingWriters == 0 && activeWriters == 0;
92
}
93![](/Images/OutliningIndicators/InBlock.gif)
94![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//**
95
* @return true if no readers/writers are using the resouce.
96
*/
97![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
private boolean canWrite()
{
98
return activeReaders == 0 && activeWriters == 0;
99
}
100
} end