Posted on 2011-10-17 16:59
疯狂 阅读(1115)
评论(0) 编辑 收藏 所属分类:
concurrent
线程读写同一个对象的数据是很普遍的,通常,要避免读写冲突,必须保证任何时候仅有一个线程在写入,有线程正在读取的时候,写入操作就必须等待。简单说,就是要避免“写-写”冲突和“读-写”冲突。但是同时读是允许的,因为“读-读”不冲突,而且很安全。
冲jdk1.5开始可以使用ReadWriteLock类来防止读写冲突.它有一个已有的实现ReentrantReadWriteLock。
ReentrantReadWriteLock使用内部维护的读写锁来防止读写冲突;
public ReentrantReadWriteLock.WriteLock writeLock() { return writerLock; }
public ReentrantReadWriteLock.ReadLock readLock() { return readerLock; } 示例代码如下:
public class RreadWriteLockTest {
ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
public int i = 0;
//读取
public void read() throws InterruptedException{
readWriteLock.readLock().lock();//获取读锁
System.out.println("read thread:"+Thread.currentThread().getName());
Thread.sleep(10000);
System.out.println("read:"+i);
readWriteLock.readLock().unlock();
}
//写入
public void write() throws InterruptedException{
readWriteLock.writeLock().lock();//获取写锁
System.out.println("write thread:"+Thread.currentThread().getName());
Thread.sleep(10000);
i = 2;
System.out.println("write:"+i);
readWriteLock.writeLock().unlock();
}
}
测试代码:
1 测试两个同时读的,结果都能同时读取。
2 测试一个读,一个写的,需要其中一个释放锁之后才能进行另外一个操作
public static void main(String[] args) throws InterruptedException {
final RreadWriteLockTest lockTest= new RreadWriteLockTest();
new Thread(new Runnable() {
@Override
public void run() {
try {
lockTest.write();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
Thread.sleep(2000);
new Thread(new Runnable() {
@Override
public void run() {
try {
lockTest.read();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
}
打印如下:
write thread:Thread-0执行完之后(10秒之后)才执行read thread:Thread-1
注意:执行完以后一定要执行unlock,要不lock的计数没有-1,这样对应read或者write的操作将无法进行,一直等待。