JAVA并发的性能调整

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

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

 1 package com.dy.xidian;
 2 
 3 import java.util.ArrayList;
 4 import java.util.Collections;
 5 import java.util.Random;
 6 import java.util.concurrent.ExecutorService;
 7 import java.util.concurrent.Executors;
 8 import java.util.concurrent.TimeUnit;
 9 import java.util.concurrent.locks.Lock;
10 import java.util.concurrent.locks.ReentrantReadWriteLock;
11 
12 public class ReaderWriterList<T> {
13     private ArrayList<T> lockedList;
14     private ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
15     public ReaderWriterList(int size, T initialValue) {
16         lockedList = new ArrayList<T>(Collections.nCopies(size, initialValue));
17     }
18 
19     public T set(int index, T element) {
20         Lock wlock = lock.writeLock();
21         wlock.lock();
22         try {
23             return lockedList.set(index, element);
24         } finally {
25             wlock.unlock();
26         }
27     }
28 
29     public T get(int index) {
30         Lock rlock = lock.readLock();
31         rlock.lock();
32         try {
33             if (lock.getReadLockCount() > 1)
34                 System.out.println(lock.getReadLockCount());
35             return lockedList.get(index);
36         } finally {
37             lock.readLock().unlock();
38         }
39     }
40 
41     public static void main(String[] args) {
42         new ReaderWriterListTest(30, 1);
43     }
44 }
45 
46 class ReaderWriterListTest {
47     ExecutorService exec = Executors.newCachedThreadPool();
48     private final static int SIZE = 100;
49     private static Random rand = new Random(47);
50     private ReaderWriterList<Integer> list = new ReaderWriterList<Integer>(
51             SIZE, 0);
52 
53     private class Writer implements Runnable {
54 
55         @Override
56         public void run() {
57             try {
58                 for (int i = 0; i < 20; i++) {
59                     list.set(i, rand.nextInt());
60                     TimeUnit.MILLISECONDS.sleep(100);
61                 }
62             } catch (InterruptedException e) {
63                 System.out.println("interrupted!");
64             }
65             System.out.println("Writer finished, shutting down");
66         }
67     }
68 
69     private class Reader implements Runnable {
70 
71         @Override
72         public void run() {
73             try {
74                 while (!Thread.interrupted()) {
75                     for (int i = 0; i < SIZE; i++) {
76                         list.get(i);
77                         TimeUnit.MILLISECONDS.sleep(1);
78                     }
79                 }
80             } catch (InterruptedException e) {
81                 System.out.println("Read interrupted");
82             }
83         }
84     }
85 
86     public ReaderWriterListTest(int readers, int writers) {
87         for (int i = 0; i < readers; i++)
88             exec.execute(new Reader());
89         for (int i = 0; i < writers; i++)
90             exec.execute(new Writer());
91     }
92 }

 

posted @ 2016-04-10 16:05  被罚站的树  阅读(301)  评论(0编辑  收藏  举报