我試圖證明,當有許多讀者和只有一些作家同步較慢。不知何故,我證明了相反。同步與ReadWriteLock性能
的RW例如,執行時間爲313毫秒:
package zad3readWriteLockPerformance;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class Main {
public static long start, end;
public static void main(String[] args) {
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
end = System.currentTimeMillis();
System.out.println("Time of execution " + (end - start) + " ms");
}));
start = System.currentTimeMillis();
final int NUMBER_OF_THREADS = 1000;
ThreadSafeArrayList<Integer> threadSafeArrayList = new ThreadSafeArrayList<>();
ArrayList<Thread> consumerThreadList = new ArrayList<Thread>();
for (int i = 0; i < NUMBER_OF_THREADS; i++) {
Thread t = new Thread(new Consumer(threadSafeArrayList));
consumerThreadList.add(t);
t.start();
}
ArrayList<Thread> producerThreadList = new ArrayList<Thread>();
for (int i = 0; i < NUMBER_OF_THREADS/10; i++) {
Thread t = new Thread(new Producer(threadSafeArrayList));
producerThreadList.add(t);
t.start();
}
// System.out.println("Printing the First Element : " + threadSafeArrayList.get(1));
}
}
class Consumer implements Runnable {
public final static int NUMBER_OF_OPERATIONS = 100;
ThreadSafeArrayList<Integer> threadSafeArrayList;
public Consumer(ThreadSafeArrayList<Integer> threadSafeArrayList) {
this.threadSafeArrayList = threadSafeArrayList;
}
@Override
public void run() {
for (int j = 0; j < NUMBER_OF_OPERATIONS; j++) {
Integer obtainedElement = threadSafeArrayList.getRandomElement();
}
}
}
class Producer implements Runnable {
public final static int NUMBER_OF_OPERATIONS = 100;
ThreadSafeArrayList<Integer> threadSafeArrayList;
public Producer(ThreadSafeArrayList<Integer> threadSafeArrayList) {
this.threadSafeArrayList = threadSafeArrayList;
}
@Override
public void run() {
for (int j = 0; j < NUMBER_OF_OPERATIONS; j++) {
threadSafeArrayList.add((int) (Math.random() * 1000));
}
}
}
class ThreadSafeArrayList<E> {
private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
private final Lock readLock = readWriteLock.readLock();
private final Lock writeLock = readWriteLock.writeLock();
private final List<E> list = new ArrayList<>();
public void add(E o) {
writeLock.lock();
try {
list.add(o);
//System.out.println("Adding element by thread" + Thread.currentThread().getName());
} finally {
writeLock.unlock();
}
}
public E getRandomElement() {
readLock.lock();
try {
//System.out.println("Printing elements by thread" + Thread.currentThread().getName());
if (size() == 0) {
return null;
}
return list.get((int) (Math.random() * size()));
} finally {
readLock.unlock();
}
}
public int size() {
return list.size();
}
}
同步例如,執行的時間僅爲241ms:
package zad3readWriteLockPerformanceZMIENONENENASYNCHRO;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Main {
public static long start, end;
public static void main(String[] args) {
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
end = System.currentTimeMillis();
System.out.println("Time of execution " + (end - start) + " ms");
}));
start = System.currentTimeMillis();
final int NUMBER_OF_THREADS = 1000;
List<Integer> list = Collections.synchronizedList(new ArrayList<Integer>());
ArrayList<Thread> consumerThreadList = new ArrayList<Thread>();
for (int i = 0; i < NUMBER_OF_THREADS; i++) {
Thread t = new Thread(new Consumer(list));
consumerThreadList.add(t);
t.start();
}
ArrayList<Thread> producerThreadList = new ArrayList<Thread>();
for (int i = 0; i < NUMBER_OF_THREADS/10; i++) {
Thread t = new Thread(new Producer(list));
producerThreadList.add(t);
t.start();
}
// System.out.println("Printing the First Element : " + threadSafeArrayList.get(1));
}
}
class Consumer implements Runnable {
public final static int NUMBER_OF_OPERATIONS = 100;
List<Integer> list;
public Consumer(List<Integer> list) {
this.list = list;
}
@Override
public void run() {
for (int j = 0; j < NUMBER_OF_OPERATIONS; j++) {
if (list.size() > 0)
list.get((int) (Math.random() * list.size()));
}
}
}
class Producer implements Runnable {
public final static int NUMBER_OF_OPERATIONS = 100;
List<Integer> threadSafeArrayList;
public Producer(List<Integer> threadSafeArrayList) {
this.threadSafeArrayList = threadSafeArrayList;
}
@Override
public void run() {
for (int j = 0; j < NUMBER_OF_OPERATIONS; j++) {
threadSafeArrayList.add((int) (Math.random() * 1000));
}
}
}
爲什麼同步採集速度更快,當我有十倍以上讀者不是作家。如何顯示我在許多文章中讀到的RW鎖的進度?
基本閱讀:http://stackoverflow.com/questions/504103/how-do-i-write-a-correct-micro-benchmark-in-java – assylias
值得注意的是'list.get((int)( Math.random()*列表。因爲另一個線程可能會在對size和get的調用之間調用remove,導致IndexOutOfBoundsException如果第一個線程嘗試'從先前的最後一個索引獲得'。雖然這對於你的用例可能不是問題,如果'remove'永遠不會被調用。 – MikeFHay