1

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

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) 测试课

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 应该自然会读到锁。但是这种情况不会发生。有什么我想不明白的吗?

4

2 回答 2

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()

于 2013-07-27T21:53:16.957 回答
0

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

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

我不完全确定您的问题是什么,或者是否有任何问题。但是阅读更多关于并发的知识总是有帮助的。

于 2013-07-27T21:33:29.223 回答