• 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 }
  • 相关阅读:
    linux-文件
    字符串函数
    函数
    内存管理
    静态库、动态库文件制作
    Makefile 待完善
    指针
    开发板GEC6816环境搭建,使用VS code
    C语言数组
    连接开发板下载程序
  • 原文地址:https://www.cnblogs.com/xidongyu/p/5374366.html
Copyright © 2020-2023  润新知