簡體   English   中英

Java中的讀/寫鎖實現

[英]Read/Write Lock implementation in Java

我正在閱讀有關某些網頁中的鎖的信息,並試圖運行某些網站描述的基本案例。 我是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)測試成績

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應該執行自然會讀鎖。但是這種情況不會發生。是否有我缺少的東西要理解?

您完全想念的是,您的測試會啟動兩個完全不執行任何操作的線程並立即停止運行,並且其余代碼由一個線程(主線程)順序執行。

實際上,您的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()

並發乍看起來可能像是一頭野獸,這可能是因為它是不同的代碼進行形式。 對於每個線程(您的進程始終至少有一個線程),處理器會為每個線程分配少量時間進行處理。 如果您使用過Swing,那么您已經對並發有了一些經驗,因為實例化的每個JFrame是一個新線程。

由於每個線程只允許使用一小段時間,因此有可能在修改對象時將其在計算過程中停止。 如果下一個線程也嘗試修改該對象,則將收到ConcurrentModificationException。 當使用集合時,這是非常明顯的,因為許多集合不是線程安全的,包括迭代器。 這是鎖進入的地方,可防止線程同時修改同一資源。 一個線程將在對象上放置一個同步鎖,並且任何嘗試訪問該資源的線程都將被阻止,直到發出鎖的線程退出了同步部分為止。 如果您有無限循環或某個鎖中的其他線程鎖定了對象,則可能會遇到死鎖,因為帶有鎖的線程也被阻塞,因此無法繼續進行。

我不確定您的問題是什么,還是有任何問題。 但是,更多地了解並發總是有幫助的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM