Java 读/写锁定比同步慢,即使仅在读取时也是如此?
我有以下代码ArrayList实现Java 读/写锁定比同步慢,即使仅在读取时也是如此?,java,concurrency,executorservice,locks,Java,Concurrency,Executorservice,Locks,我有以下代码ArrayList实现 public class LongArrayListUnsafe { public static void main(String[] args) { LongArrayList dal1 = LongArrayList.withElements(); for (int i = 0; i < 1000; i++) dal1.add(i); // Runtime.getRun
public class LongArrayListUnsafe {
public static void main(String[] args) {
LongArrayList dal1 = LongArrayList.withElements();
for (int i = 0; i < 1000; i++)
dal1.add(i);
// Runtime.getRuntime().availableProcessors()
ExecutorService executorService = Executors.newFixedThreadPool(4);
long start = System.nanoTime();
for (int i = 0; i < 100; i++) {
executorService.execute(new Runnable() {
public void run() {
for (int i = 0; i < 1000; i++)
dal1.size();
for (int i = 0; i < 1000; i++)
dal1.get(i % 100);
}
});
}
executorService.shutdown();
try {
executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
} catch (InterruptedException e) {
System.out.println("mayor disaster!");
}
}
class LongArrayList {
private long[] items;
private int size;
public LongArrayList() {
reset();
}
public static LongArrayList withElements(long...initialValues) {
LongArrayList list = new LongArrayList();
for (long l: initialValues)
list.add(l);
return list;
}
// Number of items in the double list
public synchronized int size() {
return size;
}
// Return item number i
public synchronized long get(int i) {
if (0 <= i && i < size)
return items[i];
else
throw new IndexOutOfBoundsException(String.valueOf(i));
}
// Add item x to end of list
public synchronized LongArrayList add(long x) {
if (size == items.length) {
long[] newItems = new long[items.length * 2];
for (int i = 0; i < items.length; i++)
newItems[i] = items[i];
items = newItems;
}
items[size] = x;
size++;
return this;
}
及
public long get(int i){
readWriteLock.readLock().lock();
if(0A本质上比互斥锁(如synchronized
)更复杂。该类的文档说明了这一点。读写语义的开销可能大于返回此.size;
,或返回此.items[i];
,即使有周围的边界检查
让我们特别看看你的提案。你想替换原来的提案吗
public synchronized int size() {
return size;
}
赞成这个提议
synchronized public int size() { // <-- locks exclusively/mutually on "this"
readWriteLock.readLock().lock(); // <-- locks on readWriteLock.readLock()
int ret = this.size.get(); // <-- is size and AtomicInteger now?
readWriteLock.readLock().unlock();
return ret;
}
get(int)
的实现是危险的。如果抛出indexootfboundexception
,读取锁将永远保持锁定状态。这不会降低进一步读取的速度,但会保留将来对add(long)的所有调用
等待。如果使用锁,建议将其与最后一起使用,以确保其解锁:
public long get(int i) {
readWriteLock.readLock().lock();
try {
if (0 <= i && i < size) {
return items[i];
}
throw new IndexOutOfBoundsException(String.valueOf(i));
}
finally {
readWriteLock.readLock().unlock();
}
}
public LongArrayList add(long x) {
readWriteLock.writeLock().lock();
try {
if (size == items.length) {
long[] newItems = new long[items.length * 2];
for (int i = 0; i < items.length; i++)
newItems[i] = items[i];
items = newItems;
}
items[size] = x;
size++;
}
finally {
readWriteLock.writeLock().unlock();
}
return this;
}
public long get(int i){
readWriteLock.readLock().lock();
试一试{
如果(0)get方法周围的readWriteLock
不限制该方法一次只能调用一次吗?在get完成之前,没有其他人可以读取。@RobertHarvey From:“读取锁可以由多个读线程同时持有,只要没有写入程序。”我可能误解了readlock,但我的理解是,readlock只在writelock被访问的情况下才锁定。并且readlocks可以在同一时间被访问请参见:---您肯定违反了规则1。@Andreas事实上它违反了每一点。最值得注意的是,基准操作重复执行查询y,其结果完全未使用,因此代码只是测量Jit应用死代码消除的速度(或是否)。事实上,synchronized
从中受益的可能性更高。
synchronized public int size() { // <-- locks exclusively/mutually on "this"
readWriteLock.readLock().lock(); // <-- locks on readWriteLock.readLock()
int ret = this.size.get(); // <-- is size and AtomicInteger now?
readWriteLock.readLock().unlock();
return ret;
}
public int size() {
readWriteLock.readLock().lock();
int ret = this.size;
readWriteLock.readLock().unlock();
return ret;
}
public long get(int i) {
readWriteLock.readLock().lock();
if (0 <= i && i < this.size) {
long ret = items[i];
readWriteLock.readLock().unlock();
return ret;
} else {
throw new IndexOutOfBoundsException(String.valueOf(i));
}
}
public LongArrayList add(long x) {
readWriteLock.writeLock().lock();
if (size == items.length) {
long[] newItems = new long[items.length * 2];
for (int i = 0; i < items.length; i++)
newItems[i] = items[i];
this.items = newItems;
}
items[size] = x;
size++;
readWriteLock.writeLock().unlock();
return this;
}
public long get(int i) {
readWriteLock.readLock().lock();
try {
if (0 <= i && i < size) {
return items[i];
}
throw new IndexOutOfBoundsException(String.valueOf(i));
}
finally {
readWriteLock.readLock().unlock();
}
}
public LongArrayList add(long x) {
readWriteLock.writeLock().lock();
try {
if (size == items.length) {
long[] newItems = new long[items.length * 2];
for (int i = 0; i < items.length; i++)
newItems[i] = items[i];
items = newItems;
}
items[size] = x;
size++;
}
finally {
readWriteLock.writeLock().unlock();
}
return this;
}