在Java中, sync關鍵字用于獲取對象的排他鎖。 當線程獲取對象的鎖以進行讀取或寫入時,其他線程必須等待,直到該對象的鎖被釋放。 想想一個場景,有許多讀取器線程經常讀取共享數據,而只有一個寫入器線程更新共享數據。 讀取時不必排他地鎖定對共享數據的訪問,因為除非有寫入操作,否則可以并行執行多個讀取操作。
在本文中,我將提供Java 1.5 API文檔中引入的ReadWriteLock接口的示例用法。 在Java Api文檔中,它說:
ReadWriteLock維護一對關聯的鎖,
一種用于只讀操作,另一種用于寫操作。
讀取鎖可以由多個讀取器線程同時保持,
只要沒有作家。 寫鎖是排他的。
讀取器線程可以同時讀取共享數據。 讀取操作不會阻止其他讀取操作。 執行SQL SELECT語句時就是這種情況。 但是寫操作是排他的。 這意味著當寫入器線程持有用于修改共享數據的鎖時,所有讀取器和其他寫入器均被阻止。
Writer.java此類表示更新共享數據的線程。 Writer使用ReadWriteLock的WriteLock專門鎖定對字典的訪問。
package deneme.readwritelock;public class Writer extends Thread{private boolean runForestRun = true;private Dictionary dictionary = null;public Writer(Dictionary d, String threadName) {this.dictionary = d;this.setName(threadName);}@Overridepublic void run() {while (this.runForestRun) { String [] keys = dictionary.getKeys();for (String key : keys) {String newValue = getNewValueFromDatastore(key);//updating dictionary with WRITE LOCKdictionary.set(key, newValue);}//update every secondstry {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}public void stopWriter(){this.runForestRun = false;this.interrupt();}public String getNewValueFromDatastore(String key){//This part is not implemented. Out of scope of this artilereturn "newValue";}}
Reader.java此類表示讀取共享數據的線程。
package deneme.readwritelock;public class Reader extends Thread{private Dictionary dictionary = null;public Reader(Dictionary d, String threadName) {this.dictionary = d;this.setName(threadName);}private boolean runForestRun = true;@Overridepublic void run() {while (runForestRun) {String [] keys = dictionary.getKeys();for (String key : keys) {//reading from dictionary with READ LOCKString value = dictionary.get(key);//make what ever you want with the value.System.out.println(key + " : " + value);}//update every secondstry {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}public void stopReader(){this.runForestRun = false;this.interrupt();}}
Dictionary.java這是一個簡單且線程安全的字典。 讀操作通過ReadLock進行管理,寫操作(更新)通過WriteLock進行管理。
package deneme.readwritelock;import java.util.HashMap;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantReadWriteLock;public class Dictionary {private final ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();private final Lock read = readWriteLock.readLock();private final Lock write = readWriteLock.writeLock();private HashMap<String, String> dictionary = new HashMap<String, String>();public void set(String key, String value) {write.lock();try {dictionary.put(key, value);} finally {write.unlock();}}public String get(String key) {read.lock();try{return dictionary.get(key);} finally {read.unlock();}}public String[] getKeys(){read.lock();try{String keys[] = new String[dictionary.size()];return dictionary.keySet().toArray(keys);} finally {read.unlock();}}public static void main(String[] args) {Dictionary dictionary = new Dictionary();dictionary.set("java", "object oriented");dictionary.set("linux", "rulez");Writer writer = new Writer(dictionary, "Mr. Writer");Reader reader1 = new Reader(dictionary ,"Mrs Reader 1");Reader reader2 = new Reader(dictionary ,"Mrs Reader 2");Reader reader3 = new Reader(dictionary ,"Mrs Reader 3");Reader reader4 = new Reader(dictionary ,"Mrs Reader 4");Reader reader5 = new Reader(dictionary ,"Mrs Reader 5");writer.start();reader1.start();reader2.start();reader3.start();reader4.start();reader5.start();}}
參考:來自我們的JCG合作伙伴 Ilkin Ulas的Java中的ReadWriteLock示例, 您的所有博客都屬于我們博客。
翻譯自: https://www.javacodegeeks.com/2012/04/java-concurrency-with-readwritelock.html