您的位置:首页 > 编程语言 > Java开发

JAVA并发的性能调整

2016-04-10 16:05 711 查看

1.互斥技术

synchronized

Lock

Atomic

  性能比较Atomic > Lock > synchronized,当然这不是绝对的。当线程数比较少时,synchronized的效率还是很可观的,并且用这个关键修饰的代码块阅读性很强。所以我们在编程时首先考虑到使用synchronized,当对并发的性能要求高的时候,才考虑使用Lock或者Atomic。Atomic适合简答的对象,如果对象多于复杂,不建议使用。

2.免锁容器

 CopyOnWriteArrayList

CopyOnWriteArraySet

concurrentHashMap

ConcurrentLinkedQueue

  在介绍勉锁容器时,先了解一下cow(copy on write)技术。该技术使用的对象一般是类似于数组这样存储量比较大的数据格式。在使用cow技术对数组进行写操作的时候,首先会对原始数组进行建立一个副本,然后对这个副本进行写操作。等到写操作完成后,通过一个原子操作将引用指向这个修改后的副本。这个写操作时互斥的,所以在某一时间段内只有一个线程对数组进行写操作。

  在容器中引入cow技术后就是所谓的免锁容器,如CopyOnWriteArrayList。在免锁容器中,对数据的读和写操作可以同时发生,减少了获取锁和释放锁的操作。不过有一点需要注意,读到的始终是原数据的值。

  免锁容器一般使用的场景是数据量比较少,读次数多,写次数少。

3.ReadWriteLock

  该锁是针对写操作少,读操作多的情况使用。多个读者进行读操作时,不会产生冲突。当读锁被持有时,写操作不能进行。当写锁被其它任务持有时,任何读者都不能进行读操作,直到写锁被释放。

package com.dy.xidian;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class ReaderWriterList<T> {
private ArrayList<T> lockedList;
private ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
public ReaderWriterList(int size, T initialValue) {
lockedList = new ArrayList<T>(Collections.nCopies(size, initialValue));
}

public T set(int index, T element) {
Lock wlock = lock.writeLock();
wlock.lock();
try {
return lockedList.set(index, element);
} finally {
wlock.unlock();
}
}

public T get(int index) {
Lock rlock = lock.readLock();
rlock.lock();
try {
if (lock.getReadLockCount() > 1)
System.out.println(lock.getReadLockCount());
return lockedList.get(index);
} finally {
lock.readLock().unlock();
}
}

public static void main(String[] args) {
new ReaderWriterListTest(30, 1);
}
}

class ReaderWriterListTest {
ExecutorService exec = Executors.newCachedThreadPool();
private final static int SIZE = 100;
private static Random rand = new Random(47);
private ReaderWriterList<Integer> list = new ReaderWriterList<Integer>(
SIZE, 0);

private class Writer implements Runnable {

@Override
public void run() {
try {
for (int i = 0; i < 20; i++) {
list.set(i, rand.nextInt());
TimeUnit.MILLISECONDS.sleep(100);
}
} catch (InterruptedException e) {
System.out.println("interrupted!");
}
System.out.println("Writer finished, shutting down");
}
}

private class Reader implements Runnable {

@Override
public void run() {
try {
while (!Thread.interrupted()) {
for (int i = 0; i < SIZE; i++) {
list.get(i);
TimeUnit.MILLISECONDS.sleep(1);
}
}
} catch (InterruptedException e) {
System.out.println("Read interrupted");
}
}
}

public ReaderWriterListTest(int readers, int writers) {
for (int i = 0; i < readers; i++)
exec.execute(new Reader());
for (int i = 0; i < writers; i++)
exec.execute(new Writer());
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: