两个读取相同资源的线程是不会为彼此造成麻烦的,同样地多个线程读取相同资源的线程同时进行读操作也没有问题的。但当某个单独的线程要对资源进行写操作时,必须要求没有其他的线程在对该资源进行读操作或写操作。
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
class ReadWriteLock {
private volatile int reader_cnt = 0;
private volatile int writer_cnt = 0;
private final ReentrantLock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
public void readLock() {
lock.lock();
try {
while (writer_cnt > 0) {
try {
condition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
reader_cnt++;
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void readUnlock() {
lock.lock();
try {
reader_cnt--;
condition.signalAll();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void writeLock() {
lock.lock();
try {
while (writer_cnt > 0 || reader_cnt > 0) {
try {
condition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
writer_cnt++;
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void writeUnlock() {
lock.lock();
try {
writer_cnt--;
condition.signalAll();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
public class Main {
// private final static ReentrantReadWriteLock lock=new
// ReentrantReadWriteLock();
private final static ReadWriteLock read_write_lock = new ReadWriteLock();
private static class Reader extends Thread {
private int i = 0;
public Reader(int i) {
super();
this.i = i;
}
@Override
public void run() {
while (true) {
// lock.readLock().lock();
read_write_lock.readLock();
System.out.println("i am reading" + " " + i);
// lock.readLock().unlock();
read_write_lock.readUnlock();
try {
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
private static class Writer extends Thread {
@Override
public void run() {
while (true) {
// lock.writeLock().lock();
read_write_lock.writeLock();
System.out.println("i am writing");
// lock.writeLock().unlock();
read_write_lock.writeUnlock();
try {
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) throws InterruptedException {
Thread reader1 = new Reader(1);
Thread reader2 = new Reader(2);
Thread writer = new Writer();
reader1.join();
reader2.join();
writer.join();
reader1.start();
reader2.start();
writer.start();
}
}