Java 在我的示例中,为什么RW lock比synchronized慢100ms
我想展示RW锁和同步锁在性能上的差异。我已经完成了锁定部分,但是我遇到了Java 在我的示例中,为什么RW lock比synchronized慢100ms,java,multithreading,synchronized,Java,Multithreading,Synchronized,我想展示RW锁和同步锁在性能上的差异。我已经完成了锁定部分,但是我遇到了synchronized的问题。add方法由Producer线程调用,getRandomElement()由Consumer线程调用。我想强制执行add()方法,当没有人执行getRandomElement()方法时,执行getRandomElement()方法;当没有人使用synchronizedword执行add()方法时,执行getRandomElement()方法 可能吗 import java.util.Array
synchronized
的问题。add
方法由Producer
线程调用,getRandomElement()
由Consumer
线程调用。我想强制执行add()
方法,当没有人执行getRandomElement()
方法时,执行getRandomElement()
方法;当没有人使用synchronized
word执行add()
方法时,执行getRandomElement()
方法
可能吗
import java.util.ArrayList;
import java.util.List;
public class ThreadSafeArrayList<E> {
private final List<E> list = new ArrayList<>();
private final Object m = new Object();
public void add(E o) {
synchronized (m) {
list.add(o);
System.out.println("Adding element by thread" + Thread.currentThread().getName());
}
}
public E getRandomElement() {
synchronized (m) {
System.out.println("Printing elements by thread" + Thread.currentThread().getName());
if (size() == 0) {
return null;
}
return list.get((int) (Math.random() * size()));
}
}
public int size() {
return list.size();
}
}
主要问题是:
import java.util.ArrayList;
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) + " milisekund");
}));
start = System.currentTimeMillis();
final int NUMBER_OF_THREADS = 100;
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; i++) {
Thread t = new Thread(new Producer(threadSafeArrayList));
producerThreadList.add(t);
t.start();
}
// System.out.println("Printing the First Element : " + threadSafeArrayList.get(1));
}
}
import java.util.ArrayList;
公共班机{
公共静态长起点、终点;
公共静态void main(字符串[]args){
Runtime.getRuntime().addShutdownHook(新线程(()->{
end=System.currentTimeMillis();
System.out.println(“执行时间”+(结束-开始)+“milisekund”);
}));
start=System.currentTimeMillis();
螺纹的最终整数=100;
ThreadSafeArrayList ThreadSafeArrayList=新的ThreadSafeArrayList();
ArrayList consumerThreadList=新建ArrayList();
for(int i=0;i<线程数;i++){
线程t=新线程(新使用者(threadSafeArrayList));
消费者阅读列表。添加(t);
t、 start();
}
ArrayList producerThreadList=新建ArrayList();
for(int i=0;i<线程数;i++){
线程t=新线程(新生产者(threadSafeArrayList));
生产商阅读列表。添加(t);
t、 start();
}
//System.out.println(“打印第一个元素:+threadSafeArrayList.get(1));
}
}
以下是方法。您可能需要尝试并修复while循环。此外,您可能需要同步列表对象而不是包含类方法
public synchronized void add(E o) {
try {
list.add(o);
notifyAll();
System.out.println("Adding element by thread" + Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public synchronized E getRandomElement() {
try {
System.out.println("Printing elements by thread" + Thread.currentThread().getName());
while(true){
wait();
if(list.size()>0) break;
}
E ret = list.get((int) (Math.random() * size()));
return ret;
} catch (Exception e) {
return null;
}
}
看看
wait/notify
@sidgate知道这些,现在它们是如何工作的,但是当有一个以上的生产者和一个消费者时,我永远不知道如何使用它们。它仍然有效,wait
对于消费者和notifyAll
对于生产者task@sidgate像这样:?我得到了死锁。@Yoda我知道您只使用了类的一个实例(在生产者和所有消费者之间)。这段代码应该可以正常工作。在我删除add中不可访问的catch块并运行程序后,它不会编译,我得到了死锁。
public 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();
}
}
}
import java.util.ArrayList;
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) + " milisekund");
}));
start = System.currentTimeMillis();
final int NUMBER_OF_THREADS = 100;
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; i++) {
Thread t = new Thread(new Producer(threadSafeArrayList));
producerThreadList.add(t);
t.start();
}
// System.out.println("Printing the First Element : " + threadSafeArrayList.get(1));
}
}
public synchronized void add(E o) {
try {
list.add(o);
notifyAll();
System.out.println("Adding element by thread" + Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public synchronized E getRandomElement() {
try {
System.out.println("Printing elements by thread" + Thread.currentThread().getName());
while(true){
wait();
if(list.size()>0) break;
}
E ret = list.get((int) (Math.random() * size()));
return ret;
} catch (Exception e) {
return null;
}
}