[英]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.