public class Foo {
private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
private final Lock r = rwl.readLock();
private final Lock w = rwl.writeLock();
public void read() {
try {
r.lock();
Thread.sleep(1000);
System.out.println("read...");
} catch (Exception e) {
e.printStackTrace();
} finally {
r.unlock();
}
}
public void wirte() {
try {
w.lock();
Thread.sleep(1000);
System.out.println("writing...");
} catch (Exception e) {
e.printStackTrace();
} finally {
w.lock();
}
}
}
上面是我在书上看到的代码书上说让我写一个实现runnable接口的类然后测试读写锁我没明白,谁能解释下?
首先,你这个Foo对象必须是被多个线程共享的,然后定义两个任务,一个执行读操作,另一个任务执行写操作,然后定义2个写线程,5个读线程,测试这些线程分别执行读、写操作时不同锁的特点。
其次,你的这个Foo类定义的write的finally分支错误了,应该是w.unlock()才对,稍微修正下你的Foo代码,输出当前线程的名称:
public class Foo {
private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
private final Lock r = rwl.readLock();
private final Lock w = rwl.writeLock();
// 读锁,允许同时N个线程进行读操作,不存在竞争
public void read() {
try {
r.lock();
Thread.sleep(10000);
System.out.println(Thread.currentThread().getName() + " read...");
} catch (Exception e) {
e.printStackTrace();
} finally {
r.unlock();
}
}
//写锁,同时允许一个线程写,明显能看到互斥等待
public void wirte() {
try {
w.lock();
Thread.sleep(3000);
System.out.println(Thread.currentThread().getName() + " writing...");
} catch (Exception e) {
e.printStackTrace();
} finally {
w.unlock();
}
}
}
定义读任务:
public class LockReadTask implements Runnable{
private Foo source;
public LockReadTask(Foo source){
this.source = source;
}
@Override
public void run() {
source.read();
}
}
定义写任务:
public class LockWriteTask implements Runnable{
private Foo source;
public LockWriteTask(Foo source){
this.source = source;
}
@Override
public void run() {
source.wirte();
}
}
测试代码,定义2个写线程,看写锁的竞争状态;4个读线程,读锁步存在竞争。
public class Main {
public static void main(String[] args) {
//定义共享数据源
Foo source = new Foo();
//开启2个写线程:能明显看到t1,t2写线程之间的互斥等待
Thread t1 = new Thread(new LockWriteTask(source));
t1.setName("write-Thread-1");
Thread t2 = new Thread(new LockWriteTask(source));
t2.setName("write-Thread-2");
t1.start();
t2.start();
//开启5个读线程:读锁,允许同时N个线程进行操作,可以看到读打印操作同时秒出
Thread rt1 = new Thread(new LockReadTask(source));
rt1.setName("read-Thread-1");
Thread rt2 = new Thread(new LockReadTask(source));
rt2.setName("read-Thread-2");
Thread rt3 = new Thread(new LockReadTask(source));
rt3.setName("read-Thread-3");
Thread rt4 = new Thread(new LockReadTask(source));
rt4.setName("read-Thread-4");
rt1.start();
rt2.start();
rt3.start();
rt4.start();
}
}
可以看到测试结果:写线程之间有竞争,输出信息由先后;而都线程之间的读锁匙共享的,没有竞争,所以输出是同时秒出的。