lock 和 synchronized
//: concurrency/SynchronizationComparisons.java
package concurrency; /* Added by Eclipse.py */
// Comparing the performance of explicit Locks
// and Atomics versus the synchronized keyword.
import java.util.concurrent.*;
import java.util.concurrent.atomic.*;
import java.util.concurrent.locks.*;
import java.util.*;
import static net.mindview.util.Print.*;abstract class Accumulator {public static long cycles = 50000L;// Number of Modifiers and Readers during each test:private static final int N = 4;public static ExecutorService exec =Executors.newFixedThreadPool(N*2);private static CyclicBarrier barrier =new CyclicBarrier(N*2 + 1);protected volatile int index = 0;protected volatile long value = 0;protected long duration = 0;protected String id = "error";protected final static int SIZE = 100000;protected static int[] preLoaded = new int[SIZE];static {// Load the array of random numbers:Random rand = new Random(47);for(int i = 0; i
}class SynchronizedTest extends Accumulator {{ id = "synchronized"; }public synchronized void accumulate() {value += preLoaded[index++];if(index >= SIZE) index = 0;}public synchronized long read() {return value;}
}class LockTest extends Accumulator {{ id = "Lock"; }private Lock lock = new ReentrantLock();public void accumulate() {lock.lock();try {value += preLoaded[index++];if(index >= SIZE) index = 0;} finally {lock.unlock();}}public long read() {lock.lock();try {return value;} finally {lock.unlock();}}
}class AtomicTest extends Accumulator {{ id = "Atomic"; }private AtomicInteger index = new AtomicInteger(0);private AtomicLong value = new AtomicLong(0);public void accumulate() {// Oops! Relying on more than one Atomic at// a time doesn't work. But it still gives us// a performance indicator:int i = index.getAndIncrement();if( index.get()
}public class SynchronizationComparisons {static BaseLine baseLine = new BaseLine();static SynchronizedTest synch = new SynchronizedTest();static LockTest lock = new LockTest();static AtomicTest atomic = new AtomicTest();static void test() {print("============================");printf("%-12s : %13d\n", "Cycles", Accumulator.cycles);baseLine.timedTest();synch.timedTest();lock.timedTest();atomic.timedTest();Accumulator.report(synch, baseLine);Accumulator.report(lock, baseLine);Accumulator.report(atomic, baseLine);Accumulator.report(synch, lock);Accumulator.report(synch, atomic);Accumulator.report(lock, atomic);}public static void main(String[] args) {int iterations = 5; // Defaultif(args.length > 0) // Optionally change iterationsiterations = new Integer(args[0]);// The first time fills the thread pool:print("Warmup");baseLine.timedTest();// Now the initial test doesn't include the cost// of starting the threads for the first time.// Produce multiple data points:for(int i = 0; i
输出结果:
Connected to the target VM, address: '127.0.0.1:62371', transport: 'socket'
Warmup
BaseLine : 21694209
============================
Cycles : 50000
BaseLine : 2180204
synchronized : 42437398
Lock : 30372376
Atomic : 26275467
synchronized/BaseLine : 19.46
Lock/BaseLine : 13.93
Atomic/BaseLine : 12.05
synchronized/Lock : 1.40
synchronized/Atomic : 1.62
Lock/Atomic : 1.16
============================
Cycles : 100000
BaseLine : 5193179
synchronized : 82977464
Lock : 31370928
Atomic : 11210371
synchronized/BaseLine : 15.98
Lock/BaseLine : 6.04
Atomic/BaseLine : 2.16
synchronized/Lock : 2.65
synchronized/Atomic : 7.40
Lock/Atomic : 2.80
============================
Cycles : 200000
BaseLine : 8938838
synchronized : 165124963
Lock : 78268801
Atomic : 13180858
synchronized/BaseLine : 18.47
Lock/BaseLine : 8.76
Atomic/BaseLine : 1.47
synchronized/Lock : 2.11
synchronized/Atomic : 12.53
Lock/Atomic : 5.94
============================
Cycles : 400000
BaseLine : 24426392
synchronized : 331777960
Lock : 115546684
Atomic : 29905100
synchronized/BaseLine : 13.58
Lock/BaseLine : 4.73
Atomic/BaseLine : 1.22
synchronized/Lock : 2.87
synchronized/Atomic : 11.09
Lock/Atomic : 3.86
============================
Cycles : 800000
BaseLine : 34345855
synchronized : 633854425
Lock : 245733266
Atomic : 87583065
synchronized/BaseLine : 18.46
Lock/BaseLine : 7.15
Atomic/BaseLine : 2.55
synchronized/Lock : 2.58
synchronized/Atomic : 7.24
Lock/Atomic : 2.81
============================
Cycles : 1600000
BaseLine : 62631708
synchronized : 1594457825
Lock : 654792500
Atomic : 138332107
synchronized/BaseLine : 25.46
Lock/BaseLine : 10.45
Atomic/BaseLine : 2.21
synchronized/Lock : 2.44
synchronized/Atomic : 11.53
Lock/Atomic : 4.73
============================
Cycles : 3200000
BaseLine : 128165186
synchronized : 3528972948
Lock : 1278760479
Atomic : 285986269
synchronized/BaseLine : 27.53
Lock/BaseLine : 9.98
Atomic/BaseLine : 2.23
synchronized/Lock : 2.76
synchronized/Atomic : 12.34
Lock/Atomic : 4.47
============================
Cycles : 6400000
BaseLine : 220485251
synchronized : 6981991134
Lock : 2650398226
Atomic : 500422566
synchronized/BaseLine : 31.67
Lock/BaseLine : 12.02
Atomic/BaseLine : 2.27
synchronized/Lock : 2.63
synchronized/Atomic : 13.95
Lock/Atomic : 5.30
整理成表格:
no | Cycles | BaseLine | synchronized | Lock | Atomic |
1 | 50000 | 2180204 | 42437398 | 30372376 | 26275467 |
2 | 100000 | 5193179 | 82977464 | 31370928 | 11210371 |
3 | 200000 | 8938838 | 165124963 | 78268801 | 13180858 |
4 | 400000 | 24426392 | 331777960 | 115546684 | 29905100 |
5 | 800000 | 34345855 | 633854425 | 245733266 | 87583065 |
6 | 1600000 | 62631708 | 1594457825 | 654792500 | 138332107 |
7 | 3200000 | 128165186 | 3528972948 | 1278760479 | 285986269 |
8 | 6400000 | 220485251 | 6981991134 | 2650398226 | 500422566 |
使用 Lock 通常会比使用 synchronized 要高效
CopyOnWriteArrayList是Java并发包中提供的一个并发容器,它是个线程安全且读操作无锁的ArrayList,写操作则通过创建底层数组的新副本来实现,是一种读写分离的并发策略,我们也可以称这种容器为"写时复制器",Java并发包中类似的容器还有CopyOnWriteSet。
优缺点分析
了解了CopyOnWriteArrayList的实现原理,分析它的优缺点及使用场景就很容易了。
优点:
读操作性能很高,因为无需任何同步措施,比较适用于读多写少的并发场景。Java的list在遍历时,若中途有别的线程对list容器进行修改,则会抛出ConcurrentModificationException异常。而CopyOnWriteArrayList由于其"读写分离"的思想,遍历和修改操作分别作用在不同的list容器,所以在使用迭代器进行遍历时候,也就不会抛出ConcurrentModificationException异常了
缺点:
缺点也很明显,一是内存占用问题,毕竟每次执行写操作都要将原容器拷贝一份,数据量大时,对内存压力较大,可能会引起频繁GC;二是无法保证实时性,Vector对于读写操作均加锁同步,可以保证读和写的强一致性。而CopyOnWriteArrayList由于其实现策略的原因,写和读分别作用在新老不同容器上,在写操作执行过程中,读不会阻塞但读取到的却是老容器的数据。
CopyOnWriteArraySet 将使用CopyOnWriteArrayList来实现其免锁行为
ConcurrentHashMap和 ConcurrentLinkedQueue 使用了类似的技术,允许并发的读取和写入.但是容器中只有部分内容而不是整个容器可以被复制和修改.
ConcurrentHashMap不会抛出 ConcurrentModificationException.
Type Read time Write time
Synched ArrayList 10r 0w 3975043910 0
Synched ArrayList 10r 0w 2766145687 0
Synched ArrayList 10r 0w 2324410921 0
Synched ArrayList 10r 0w 2352972749 0
Synched ArrayList 10r 0w 2511789031 0
Synched ArrayList 10r 0w 2987712606 0
Synched ArrayList 10r 0w 2602829236 0
Synched ArrayList 10r 0w 3502788085 0
Synched ArrayList 10r 0w 4335015877 0
Synched ArrayList 10r 0w 4047738828 0CopyOnWriteArrayList 10r 0w 127857882 0
CopyOnWriteArrayList 10r 0w 62679837 0
CopyOnWriteArrayList 10r 0w 54443863 0
CopyOnWriteArrayList 10r 0w 56359211 0
CopyOnWriteArrayList 10r 0w 74350707 0
CopyOnWriteArrayList 10r 0w 62574412 0
CopyOnWriteArrayList 10r 0w 60151492 0
CopyOnWriteArrayList 10r 0w 68195080 0
CopyOnWriteArrayList 10r 0w 74290655 0
CopyOnWriteArrayList 10r 0w 62879388 0预计相差 40 倍Synched ArrayList 9r 1w 4351248439 519078520
readTime + writeTime = 4870326959
Synched ArrayList 9r 1w 4580132832 528211025
readTime + writeTime = 5108343857
Synched ArrayList 9r 1w 4535477318 530243150
readTime + writeTime = 5065720468
Synched ArrayList 9r 1w 3729192259 449021236
readTime + writeTime = 4178213495
Synched ArrayList 9r 1w 4310570520 516373800
readTime + writeTime = 4826944320
Synched ArrayList 9r 1w 3727406116 444126621
readTime + writeTime = 4171532737
Synched ArrayList 9r 1w 5088467838 581730237
readTime + writeTime = 5670198075
Synched ArrayList 9r 1w 3871264858 467694613
readTime + writeTime = 4338959471
Synched ArrayList 9r 1w 3907490866 475651205
readTime + writeTime = 4383142071
Synched ArrayList 9r 1w 4857326451 572377421
readTime + writeTime = 5429703872CopyOnWriteArrayList 9r 1w 64259585 58038121
readTime + writeTime = 122297706
CopyOnWriteArrayList 9r 1w 103041865 55306617
readTime + writeTime = 158348482
CopyOnWriteArrayList 9r 1w 76859340 45666997
readTime + writeTime = 122526337
CopyOnWriteArrayList 9r 1w 82963384 49150571
readTime + writeTime = 132113955
CopyOnWriteArrayList 9r 1w 85530058 47494007
readTime + writeTime = 133024065
CopyOnWriteArrayList 9r 1w 156166751 61169655
readTime + writeTime = 217336406
CopyOnWriteArrayList 9r 1w 102234854 50495800
readTime + writeTime = 152730654
CopyOnWriteArrayList 9r 1w 118083485 59992123
readTime + writeTime = 178075608
CopyOnWriteArrayList 9r 1w 168668483 60294659
readTime + writeTime = 228963142
CopyOnWriteArrayList 9r 1w 83152493 52633779
readTime + writeTime = 135786272预计相差 30 倍Synched ArrayList 5r 5w 1859681520 3059611972
readTime + writeTime = 4919293492
Synched ArrayList 5r 5w 2339497789 3231858118
readTime + writeTime = 5571355907
Synched ArrayList 5r 5w 1759631869 2999467850
readTime + writeTime = 4759099719
Synched ArrayList 5r 5w 1872095383 3013864853
readTime + writeTime = 4885960236
Synched ArrayList 5r 5w 2991087849 3226872592
readTime + writeTime = 6217960441
Synched ArrayList 5r 5w 2434089947 3523933235
readTime + writeTime = 5958023182
Synched ArrayList 5r 5w 2536545986 3119941132
readTime + writeTime = 5656487118
Synched ArrayList 5r 5w 2571197431 3003374484
readTime + writeTime = 5574571915
Synched ArrayList 5r 5w 2222675410 2791449002
readTime + writeTime = 5014124412
Synched ArrayList 5r 5w 1583914850 2689629756
readTime + writeTime = 4273544606CopyOnWriteArrayList 5r 5w 142259670 1206935112
readTime + writeTime = 1349194782
CopyOnWriteArrayList 5r 5w 49615047 995217184
readTime + writeTime = 1044832231
CopyOnWriteArrayList 5r 5w 31987043 977226939
readTime + writeTime = 1009213982
CopyOnWriteArrayList 5r 5w 66506805 1040415224
readTime + writeTime = 1106922029
CopyOnWriteArrayList 5r 5w 35032835 994549959
readTime + writeTime = 1029582794
CopyOnWriteArrayList 5r 5w 38461110 1002445848
readTime + writeTime = 1040906958
CopyOnWriteArrayList 5r 5w 50651685 1071667187
readTime + writeTime = 1122318872
CopyOnWriteArrayList 5r 5w 32006848 1001262532
readTime + writeTime = 1033269380
CopyOnWriteArrayList 5r 5w 36295220 1011740649
readTime + writeTime = 1048035869
CopyOnWriteArrayList 5r 5w 34283434 1050960270
readTime + writeTime = 1085243704预计相差 4 倍
CopyOnWriteArrayList性能 要比 SynchronizedArrayList 性能好一些. 当读的情况多的时候,会有几十倍的差距.
当读写数据量大小趋向于平均时, 性能还有将近四倍的差距.
Type Read time Write time
Synched HashMap 10r 0w 6242418056 0
Synched HashMap 10r 0w 4146402296 0
Synched HashMap 10r 0w 5575418578 0
Synched HashMap 10r 0w 3834073584 0
Synched HashMap 10r 0w 5194782005 0
Synched HashMap 10r 0w 5161536963 0
Synched HashMap 10r 0w 4444520893 0
Synched HashMap 10r 0w 3871868695 0
Synched HashMap 10r 0w 4408989207 0
Synched HashMap 10r 0w 8023118598 0ConcurrentHashMap 10r 0w 344685546 0
ConcurrentHashMap 10r 0w 346848415 0
ConcurrentHashMap 10r 0w 318704071 0
ConcurrentHashMap 10r 0w 405478178 0
ConcurrentHashMap 10r 0w 207930162 0
ConcurrentHashMap 10r 0w 366067455 0
ConcurrentHashMap 10r 0w 226500276 0
ConcurrentHashMap 10r 0w 296423990 0
ConcurrentHashMap 10r 0w 320249183 0
ConcurrentHashMap 10r 0w 508154405 0读取性能差 10 倍以上Synched HashMap 9r 1w 6513091741 753915689
readTime + writeTime = 7267007430
Synched HashMap 9r 1w 6028976406 641421250
readTime + writeTime = 6670397656
Synched HashMap 9r 1w 5676651670 653679779
readTime + writeTime = 6330331449
Synched HashMap 9r 1w 5908498114 494457577
readTime + writeTime = 6402955691
Synched HashMap 9r 1w 7834818531 844974551
readTime + writeTime = 8679793082
Synched HashMap 9r 1w 5914246757 645557937
readTime + writeTime = 6559804694
Synched HashMap 9r 1w 7138638960 744661626
readTime + writeTime = 7883300586
Synched HashMap 9r 1w 6789718783 710857815
readTime + writeTime = 7500576598
Synched HashMap 9r 1w 5310600463 599121405
readTime + writeTime = 5909721868
Synched HashMap 9r 1w 5655007305 586903118
readTime + writeTime = 6241910423ConcurrentHashMap 9r 1w 216104674 54419560
readTime + writeTime = 270524234
ConcurrentHashMap 9r 1w 294262252 40927173
readTime + writeTime = 335189425
ConcurrentHashMap 9r 1w 264142918 43273241
readTime + writeTime = 307416159
ConcurrentHashMap 9r 1w 273924527 48728635
readTime + writeTime = 322653162
ConcurrentHashMap 9r 1w 369514606 50730634
readTime + writeTime = 420245240
ConcurrentHashMap 9r 1w 219419103 38947284
readTime + writeTime = 258366387
ConcurrentHashMap 9r 1w 252190432 30225329
readTime + writeTime = 282415761
ConcurrentHashMap 9r 1w 228296180 25051090
readTime + writeTime = 253347270
ConcurrentHashMap 9r 1w 303395962 49612912
readTime + writeTime = 353008874
ConcurrentHashMap 9r 1w 171637818 35856054
readTime + writeTime = 207493872预计相差 25 倍以上.Synched HashMap 5r 5w 3787200263 3601518353
readTime + writeTime = 7388718616
Synched HashMap 5r 5w 3089274985 2733346333
readTime + writeTime = 5822621318
Synched HashMap 5r 5w 3408395059 3113962082
readTime + writeTime = 6522357141
Synched HashMap 5r 5w 3981206639 3679965007
readTime + writeTime = 7661171646
Synched HashMap 5r 5w 3265915194 3142623898
readTime + writeTime = 6408539092
Synched HashMap 5r 5w 3164752807 3000101498
readTime + writeTime = 6164854305
Synched HashMap 5r 5w 3336219924 3014104874
readTime + writeTime = 6350324798
Synched HashMap 5r 5w 3124944592 2991122381
readTime + writeTime = 6116066973
Synched HashMap 5r 5w 3977208930 3839928054
readTime + writeTime = 7817136984
Synched HashMap 5r 5w 3074772608 2874037633
readTime + writeTime = 5948810241ConcurrentHashMap 5r 5w 99540221 462089771
readTime + writeTime = 561629992
ConcurrentHashMap 5r 5w 240567089 518136870
readTime + writeTime = 758703959
ConcurrentHashMap 5r 5w 155490877 432835809
readTime + writeTime = 588326686
ConcurrentHashMap 5r 5w 220516994 483831256
readTime + writeTime = 704348250
ConcurrentHashMap 5r 5w 216032229 572084619
readTime + writeTime = 788116848
ConcurrentHashMap 5r 5w 197179986 620970499
readTime + writeTime = 818150485
ConcurrentHashMap 5r 5w 254407618 544484450
readTime + writeTime = 798892068
ConcurrentHashMap 5r 5w 208138769 501331795
readTime + writeTime = 709470564
ConcurrentHashMap 5r 5w 180873142 492012085
readTime + writeTime = 672885227
ConcurrentHashMap 5r 5w 164806795 559711679
readTime + writeTime = 724518474预计相差 10 倍以上
//: concurrency/FastSimulation.java
package concurrency; /* Added by Eclipse.py */
import java.util.concurrent.*;
import java.util.concurrent.atomic.*;
import java.util.*;
import static net.mindview.util.Print.*;public class FastSimulation {static final int N_ELEMENTS = 100000;static final int N_GENES = 30;static final int N_EVOLVERS = 50;static final AtomicInteger[][] GRID =new AtomicInteger[N_ELEMENTS][N_GENES];static Random rand = new Random(47);static class Evolver implements Runnable {public void run() {while(!Thread.interrupted()) {// Randomly select an element to work on:int element = rand.nextInt(N_ELEMENTS);for(int i = 0; i
//: concurrency/ReaderWriterList.java
package concurrency; /* Added by Eclipse.py */
import java.util.concurrent.*;
import java.util.concurrent.locks.*;
import java.util.*;
import static net.mindview.util.Print.*;public class ReaderWriterList
}class ReaderWriterListTest {ExecutorService exec = Executors.newCachedThreadPool();private final static int SIZE = 100;private static Random rand = new Random(47);private ReaderWriterList