JAVA并发的性能调整
2016-04-10 16:05
711 查看
1.互斥技术
synchronizedLock
Atomic
性能比较Atomic > Lock > synchronized,当然这不是绝对的。当线程数比较少时,synchronized的效率还是很可观的,并且用这个关键修饰的代码块阅读性很强。所以我们在编程时首先考虑到使用synchronized,当对并发的性能要求高的时候,才考虑使用Lock或者Atomic。Atomic适合简答的对象,如果对象多于复杂,不建议使用。
2.免锁容器
CopyOnWriteArrayListCopyOnWriteArraySet
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()); } }
相关文章推荐
- Spring、mybaits整合
- openjdk编译和调试
- Java的Arrays类
- BitTorrent协议java实现分析
- 20145231 《Java程序设计》第一次实验
- Java 中的 static 使用之静态变量
- Java - 待归类
- 找找 Spring Event 源码中各种设计模式的使用
- 20145240 《Java程序设计》第一次实验报告
- JAVAssist---动态改动注解
- maven+srping+springmvc+mybatis的环境搭建的每一步和代码
- myeclipse无法创建jsp页面
- 20145320《Java程序设计》第一次实验报告
- ASA用ASDM管理时报unable to launch device manage xxxx.xxx.xxx.xxx
- 20145311 实验一 "Java开发环境的熟悉"
- 20145227 《Java程序设计》第6周学习总结
- java中的接口和抽象类
- 20145210姚思羽《Java程序设计》实验一实验报告
- struts2 action
- 【java】关于static关键字在重写父类方法时的作用