Java中的读/写锁实现

时间:2013-07-27 21:19:46

标签: java multithreading locking runnable

我正在阅读一些网页中的锁,并尝试运行一些网站描述的基本案例。我是Thread使用的新手,所以这就是代码查找文件的方式,

1)读写锁定功能(非重入,非常基本)

public ReadWriteLock() {
    // TODO Auto-generated constructor stub
}



synchronized  void readLock(String name) throws InterruptedException {
    //tname = threadName;

    if(writers>0 || writereq>0){
        wait();
    }
    readers++;
    System.out.println(name + " locks for reading resource....");
}
synchronized  void readUnLock(String name) throws InterruptedException{
    //tname = threadName;
    readers--;
    System.out.println(name + "unlocks reading resource....");
    notifyAll();
}
synchronized  void writeLock(String name) throws InterruptedException{
    //tname = threadName;
    writereq++;
    if(writers>0 || readers>0){
        System.out.println( name + " waits for writing...");
        wait();
    }
    writereq--;
    writers++;
    System.out.println(" locks for writing resource....");
}
synchronized  void writeUnLock(String name) throws InterruptedException{
    //tname = threadName;
    writers--;
    System.out.println(name + " unlocks for writing resource....");
    notifyAll();

}

2)Runnable接口的实现,

public class Runner implements Runnable{

private ReadWriteLock rwl;
private String name;
public Runner(ReadWriteLock rwl, String name) {
    // TODO Auto-generated constructor stub
    this.rwl=rwl;
    this.name = name;
}

void runlocks(int method){
    //String name = Thread.currentThread().getName();
    switch(method){
    case 1:
        try {
            rwl.readLock(name);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }break;
    case 2:
        try {
            rwl.readUnLock(name);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } break;
    case 3:
        try {
            rwl.writeLock(name);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } break;
    case 4:
        try {
            rwl.writeUnLock(name);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } break;

    }
}

@Override
public void run() {
    //String name = Thread.currentThread().getName();
    // TODO Auto-generated method stub
    //System.out.println("Thread started "+ name);

    //int method = 1;
    // TODO Auto-generated method stub
    //System.out.println(this.threadName + " has started!");

}

3)测试calss

public class TestClass {
 public static void main(String[] args) throws InterruptedException {
ReadWriteLock rwl = new ReadWriteLock();
Runner r1 =new Runner(rwl,"Thread1");
Thread t1 = new Thread(r1);
t1.setName("Thread1");

Runner r2 =new Runner(rwl,"Thread2");
Thread t2 = new Thread(r2);
t2.setName("Thread2");

t1.start();
t2.start();

r1.runlocks(1); //r1 locks to read
r2.runlocks(1); //r2 locks to read
r1.runlocks(2); //r1 unlocks read
r2.runlocks(2); //r1 unlocks read

r1.runlocks(3); //r1 locks to write
r2.runlocks(1); //r2 tries to lock for read but waits.. and the code gets struck here
r1.runlocks(4);  //r1 releases lock of write
}

}

我的问题是..在测试器类中,线程1获取锁定写入,然后线程2尝试读取但它不能等待..此时,应执行下一个是线程1解锁写锁定的语句,线程2自然应该读取锁..但是这种情况不会发生。我有什么东西需要理解吗?

2 个答案:

答案 0 :(得分:1)

你完全错过的是你的测试启动两个绝对没有任何东西的线程并立即停止运行,其余代码由一个线程顺序执行:主线程。

实际上,runnable的run()方法不包含任何注释:

public void run() {
    //String name = Thread.currentThread().getName();
    // TODO Auto-generated method stub
    //System.out.println("Thread started "+ name);

    //int method = 1;
    // TODO Auto-generated method stub
    //System.out.println(this.threadName + " has started!");
}

我的建议是:阅读一篇关于线程和java.util.concurrent中的类的好教程,它提供了易于使用的高级抽象。远离wait()notify()等低级方法。

答案 1 :(得分:0)

并发最初可能看起来像野兽,这可能是因为它是代码进程的不同风格。对于您拥有的每个线程(并且您的进程始终至少有一个),处理器会为每个线程分配少量时间进行处理。如果你已经使用过Swing,那么你已经有了一些并发经验,因为每个实例化的JFrame都是一个新线程。

由于每个线程只允许很短的时间,因此在修改对象时可能会在计算过程中停止它。如果下一个线程也试图修改同一个对象,您将收到ConcurrentModificationException。在使用Collections时,这是非常明显的,因为许多不是线程安全的,包括迭代器。这是锁进入并保持线程不会同时修改同一资源的地方。一个线程将对对象进行同步锁定,并且任何尝试访问该资源的线程都将被阻塞,直到发出锁定的线程退出同步部分。如果你有一个无限循环或来自锁中其他线程的锁定对象,你可能会遇到死锁,因为带锁的线程也被阻止,因此无法取得进展。

我不完全确定你的问题是什么,或者是否有任何问题。但是在并发上阅读更多内容总是有帮助的。