1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
|
package
whut.readwritelock;
public
class
Data {
private
final
char
[] buffer;
private
final
ReadWriteLock lock=
new
ReadWriteLock();
public
Data(
int
size)
{
this
.buffer=
new
char
[size];
for
(
int
i=
0
;i<buffer.length;i++)
buffer[i]=
'*'
;
}
public
char
[] read()
throws
InterruptedException
{
lock.readLock();
try
{
return
doRead();
}
finally
{
lock.readUnlock();
}
}
private
char
[] doRead()
{
char
[] newbuf=
new
char
[buffer.length];
for
(
int
i=
0
;i<buffer.length;i++)
newbuf[i]=buffer[i];
slowly();
return
newbuf;
}
public
void
write(
char
c)
throws
InterruptedException
{
lock.writeLock();
try
{
doWrite(c);
}
finally
{
lock.writeUnlock();
}
}
private
void
doWrite(
char
c)
{
for
(
int
i=
0
;i<buffer.length;i++)
{
buffer[i]=c;
slowly();
//这里的sleep并不会切换到别的线程
//这里就是体现了使用while的好处
//当该线程sleep时候,其余等待读取的还在wait中,而要写入的线程会判断它的状态,还没有释放锁
}
}
private
void
slowly()
{
try
{
Thread.sleep(
50
);
}
catch
(InterruptedException e)
{
}
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
package
whut.readwritelock;
public
class
ReaderThread
extends
Thread{
private
final
Data data;
public
ReaderThread(Data data)
{
this
.data=data;
}
public
void
run()
{
try
{
while
(
true
)
{
char
[] readbuf=data.read();
System.out.println(Thread.currentThread().getName()
+
" reads "
+String.valueOf(readbuf));
}
}
catch
(InterruptedException e)
{
}
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
package
whut.readwritelock;
import
java.util.Random;
public
class
WriterThread
extends
Thread{
private
static
final
Random random=
new
Random();
private
final
Data data;
private
final
String filler;
private
int
index=
0
;
public
WriterThread(Data data,String filler)
{
this
.data=data;
this
.filler=filler;
}
public
void
run()
{
try
{
while
(
true
)
{
char
c=nextChar();
data.write(c);
Thread.sleep(random.nextInt(
1000
));
}
}
catch
(InterruptedException e)
{
}
}
private
char
nextChar()
{
char
c=filler.charAt(index);
index++;
if
(index>=filler.length())
index=
0
;
return
c;
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
|
package
whut.readwritelock;
//关键部分
public
class
ReadWriteLock {
private
int
readingReaders=
0
;
//实际正在读取的线程数目
private
int
waitingWriters=
0
;
//正在等待写入的线程数目
private
int
writingWriters=
0
;
//实际正在写入的线程数目
private
boolean
preferWriter=
true
;
//写入优先的话,值为true
//读取的时候获取锁
public
synchronized
void
readLock()
throws
InterruptedException
{
//当有写入的时候,或者写入为优先级并且有等待的写入线程
while
(writingWriters>
0
||(preferWriter&&waitingWriters>
0
))
{
wait();
}
readingReaders++;
}
//读完毕后释放锁
public
synchronized
void
readUnlock()
throws
InterruptedException
{
readingReaders--;
preferWriter=
true
;
notifyAll();
}
//写入的时候获取锁
public
synchronized
void
writeLock()
throws
InterruptedException
{
waitingWriters++;
//正在等待的写入的线程数目
try
{
//有写入或者读入的时候
while
(readingReaders>
0
||writingWriters>
0
)
{
wait();
}
}
finally
{
waitingWriters--;
//被唤醒了,则就是进而真正写入
}
writingWriters++;
}
//写入毕后释放锁
public
synchronized
void
writeUnlock()
throws
InterruptedException
{
writingWriters--;
preferWriter=
false
;
//写入后马上更换优先级,让读者继续
notifyAll();
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
package
whut.readwritelock;
public
class
ReadWriteMain {
public
static
void
main(String[] args) {
// TODO Auto-generated method stub
Data data=
new
Data(
10
);
//读取线程
new
ReaderThread(data).start();
new
ReaderThread(data).start();
new
ReaderThread(data).start();
new
ReaderThread(data).start();
new
ReaderThread(data).start();
new
ReaderThread(data).start();
//写入线程
new
WriterThread(data,
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
).start();
new
WriterThread(data,
"abcdefghijklmnopqrstuvwxyz"
).start();
}
}
|