多线程读取并修改一个资源时,通常使用synchronized同步锁。性能损失情况很严重。jdk5.0以后提供了新的ReentrantReadWriteLock可以提供比synchronized更高性能的并发。
Dictionary.java
package com.test;
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");
//dictionary.set("C++", "lanjh");
Writer writer = new Writer(dictionary, "Mr. Writer ");
//Writer writer2 = new Writer(dictionary, "Mr. Writer 2");
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();
//writer2.start();
reader1.start();
reader2.start();
reader3.start();
reader4.start();
reader5.start();
}
}
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");
//dictionary.set("C++", "lanjh");
Writer writer = new Writer(dictionary, "Mr. Writer ");
//Writer writer2 = new Writer(dictionary, "Mr. Writer 2");
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();
//writer2.start();
reader1.start();
reader2.start();
reader3.start();
reader4.start();
reader5.start();
}
}
Reader.java
package com.test;
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;
public void run() {
while (runForestRun) {
String [] keys = dictionary.getKeys();
for (String key : keys) {
//reading from dictionary with READ LOCK
String value = dictionary.get(key);
//make what ever you want with the value.
System.out.println(this.getName()+" = "+key + " : " + value);
}
//update every seconds
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void stopReader(){
this.runForestRun = false;
this.interrupt();
}
}
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;
public void run() {
while (runForestRun) {
String [] keys = dictionary.getKeys();
for (String key : keys) {
//reading from dictionary with READ LOCK
String value = dictionary.get(key);
//make what ever you want with the value.
System.out.println(this.getName()+" = "+key + " : " + value);
}
//update every seconds
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void stopReader(){
this.runForestRun = false;
this.interrupt();
}
}
Writer.java
package com.test;
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);
}
@Override
public void run() {
while (this.runForestRun) {
String [] keys = dictionary.getKeys();
for (String key : keys) {
String newValue = getNewValueFromDatastore(key);
//updating dictionary with WRITE LOCK
dictionary.set(key, newValue);
System.out.println(this.getName()+" = "+key + " : " + newValue);
}
//update every seconds
try {
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 artile
return key;
}
}
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);
}
@Override
public void run() {
while (this.runForestRun) {
String [] keys = dictionary.getKeys();
for (String key : keys) {
String newValue = getNewValueFromDatastore(key);
//updating dictionary with WRITE LOCK
dictionary.set(key, newValue);
System.out.println(this.getName()+" = "+key + " : " + newValue);
}
//update every seconds
try {
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 artile
return key;
}
}