繁体   English   中英

为什么在我的示例中RW锁定比同步慢100ms

[英]Why RW lock is slower by 100ms than synchronized in my example

我想展示一下性能RW锁与同步锁的区别。 我已经做了锁的一部分,但我有问题synchronized Producer线程调用add方法, Consumer线程调用getRandomElement() 我想强制使add()方法被执行而没有人执行getRandomElement()方法,以及getRandomElement()方法时,没有人执行add()的使用方法synchronized字。

可能吗?

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();
    }

}

RW版本由于某些原因而较慢,但应该更快:

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public 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();
    }

}

以下类在RW和同步版本中完全相同。

生产者类:

public 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));
        }
    }

}

Consumer类:

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));

    }

}

下面是方法。 您可能需要尝试并修复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;
    } 

}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM