简体   繁体   中英

Read/Write Lock implementation in Java

I was reading about locks in some webpages and tried to run a base case that some site described. I am new to Thread usage and so this is how the code looks for the files,

1) The Read-Write lock functions(non-reentrant, very basic)

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) An implementaiton of Runnable interface,

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) A test 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
}

}

My question is.. in the tester class, thread 1 gets lock to write, then thread 2 tries to read but it cant and waits.. At this time the next statement which is thread 1 unlocking write lock should be executed and thread 2 should naturally get to read lock.. But this scenario doesnt happen.Is there something I am missing to understand?

What you completely missed is that your test starts two threads that do absolutely nothing and stop running immediately, and that the rest of the code is performed sequentially, by a single thread: the main thread.

Indeed, the run() method of your runnable doesn contain anything but comments:

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!");
}

And my advice would be: read a good tutorial about threading and the classes in java.util.concurrent , which provide easy to use, high-level abstractions. Stay away from lowèlevel methods like wait() and notify() .

Concurrency may seem like a beast at first, and this may be because it's a different flavor of code progression. For each thread you have (And you always have at least one for your process), the processor allocates a small amount of time for processing for each thread. If you've used Swing then you have already had a bit of experience with concurrency as each JFrame instantiated is a new thread.

Since only a small time is allowed for each thread, it can potentially be stopped in the middle of calculation while modifying an object. If the next thread also attempted to modify this same object you would receive a ConcurrentModificationException. This is incredibly apparent when working with Collections as many are not thread safe, including Iterators. This is where locks come in and keep threads from modifying the same resource at the same time. One thread will put a synchronized lock on an object and any thread that tries to access that resource will be blocked until the thread issuing the lock has exited the synchronized portion. If you have an infinite loop or locked objects from other threads within a lock, you might experience a deadlock in which no progress can be made as the thread with a lock is also blocked.

I'm not entirely sure what your question was, or if there is any. But reading up a bit more on concurrency will always help.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM