美文网首页
Collection-List 安全VS不安全

Collection-List 安全VS不安全

作者: 王小杰at2019 | 来源:发表于2019-01-16 21:33 被阅读15次

@[toc]

不安全示例

package cn.wyj.learn.juc;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;

import java.util.ArrayList;
import java.util.Collection;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

@Slf4j
public class CollectionListExample2ThreadSafe {

    private static Collection list = new ArrayList();
    //运行次数
    private static final int RUN_TOTAL = 5000;
    // 并发控制
    private static final int THREAD_TOTAL = 200;


    public static void main(String[] args) throws InterruptedException {
        ExecutorService executorService = Executors.newCachedThreadPool();
        Semaphore semaphore = new Semaphore(THREAD_TOTAL);
        for (int i = 0; i < RUN_TOTAL; i++) {
            executorService.execute(() -> {
                try {
                    semaphore.acquire();
                    list.add(1);
                    semaphore.release();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
        }
        executorService.shutdown();
        // 需要等待成执行完
        executorService.awaitTermination(10, TimeUnit.SECONDS);
        log.info("list Size:{}", list.size());
    }


}


运行结果 1

21:06:36.240 [main] INFO cn.wyj.learn.juc.CollectionListExample1NoThreadSafe - list Size:4929

运行结果 2

Exception in thread "pool-1-thread-9" java.lang.ArrayIndexOutOfBoundsException: 366
    at java.util.ArrayList.add(ArrayList.java:459)
    at cn.wyj.learn.juc.CollectionListExample1NoThreadSafe.lambda$main$0(CollectionListExample1NoThreadSafe.java:28)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

安全写法1

    private static Collection list = CollectionUtils.synchronizedCollection(new ArrayList());

原因 .对原有api做了包裹处理

  /**
     * Constructor that wraps (not copies).
     * 
     * @param collection  the collection to decorate, must not be null
     * @throws IllegalArgumentException if the collection is null
     */
    protected SynchronizedCollection(Collection collection) {
        if (collection == null) {
            throw new IllegalArgumentException("Collection must not be null");
        }
        this.collection = collection;
        this.lock = this;
    }
    

    public boolean add(Object object) {
    synchronized (lock) {
        return collection.add(object);
    }
}

安全写法2

    private static Collection list = new Vector();

原因,Vector 容器本身就是安全的

 /**
     * Appends the specified element to the end of this Vector.
     *
     * @param e element to be appended to this Vector
     * @return {@code true} (as specified by {@link Collection#add})
     * @since 1.2
     */
    public synchronized boolean add(E e) {
        modCount++;
        ensureCapacityHelper(elementCount + 1);
        elementData[elementCount++] = e;
        return true;
    }

安全写法3

    private static Collection list = new CopyOnWriteArrayList();

@since 1.5

Copy-On-Write简称COW,是一种用于程序设计中的优化策略。其基本思路是,从一开始大家都在共享同一个内容,当某个人想要修改这个内容的时候,才会真正把内容Copy出去形成一个新的内容然后再改,这是一种延时懒惰策略。

容器声明

    private transient volatile Object[] array;

 /**
    * Appends the specified element to the end of this list.
    *
    * @param e element to be appended to this list
    * @return {@code true} (as specified by {@link Collection#add})
    */
   public boolean add(E e) {
       final ReentrantLock lock = this.lock;
       lock.lock();
       try {
           Object[] elements = getArray();
           int len = elements.length;
           Object[] newElements = Arrays.copyOf(elements, len + 1);
           newElements[len] = e;
           setArray(newElements);
           return true;
       } finally {
           lock.unlock();
       }
   }

 @SuppressWarnings("unchecked")
   private E get(Object[] a, int index) {
       return (E) a[index];
   }

   /**
    * {@inheritDoc}
    *
    * @throws IndexOutOfBoundsException {@inheritDoc}
    */
   public E get(int index) {
       return get(getArray(), index);
   }

image.png

安全写法4

自己实现并发控制,synchronized

package cn.wyj.learn.juc;

import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.Collection;
import java.util.concurrent.*;

@Slf4j
public class CollectionListExample5ThreadSafe {

   private static Collection list = new ArrayList();
   //运行次数
   private static final int RUN_TOTAL = 5000;
   // 并发控制
   private static final int THREAD_TOTAL = 200;


   public static void main(String[] args) throws InterruptedException {
       ExecutorService executorService = Executors.newCachedThreadPool();
       Semaphore semaphore = new Semaphore(THREAD_TOTAL);
       for (int i = 0; i < RUN_TOTAL; i++) {
           executorService.execute(() -> {
               try {
                   semaphore.acquire();
                   add();
                   semaphore.release();
               } catch (InterruptedException e) {
                   e.printStackTrace();
               }
           });
       }
       executorService.shutdown();
       // 需要等待成执行完
       executorService.awaitTermination(10, TimeUnit.SECONDS);
       log.info("list Size:{}", list.size());
   }

   private static synchronized void add() {
       list.add(1);
   }


}

安全写法5

自己实现并发控制, 重入锁

package cn.wyj.learn.juc;

import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.Collection;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

@Slf4j
public class CollectionListExample6ThreadSafe {

    private static Collection list = new ArrayList();
    //运行次数
    private static final int RUN_TOTAL = 5000;
    // 并发控制
    private static final int THREAD_TOTAL = 200;

    static Lock lock = new ReentrantLock();

    public static void main(String[] args) throws InterruptedException {
        ExecutorService executorService = Executors.newCachedThreadPool();
        Semaphore semaphore = new Semaphore(THREAD_TOTAL);
        for (int i = 0; i < RUN_TOTAL; i++) {
            executorService.execute(() -> {
                try {
                    semaphore.acquire();
                    add();
                    semaphore.release();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
        }
        executorService.shutdown();
        // 需要等待成执行完
        executorService.awaitTermination(10, TimeUnit.SECONDS);
        log.info("list Size:{}", list.size());
    }

    private static void add() {
        lock.lock();
        try {
            list.add(1);
        } finally {
            lock.unlock();
        }
    }


}

相关文章

  • Collection-List 安全VS不安全

    @[toc] 不安全示例 运行结果 1 运行结果 2 安全写法1 原因 .对原有api做了包裹处理 安全写法2 原...

  • 问题记录

    fopen函数在VS2017C++版本中不安全的问题

  • 对生命说是20190107

    生命是不安全的,只有死亡才会安全 生命是不安全的,要勇于活在不安全里面,接受生命的不安全,对生命说是,跳出舒适地带...

  • 紧缩,心慌,不安全

    小腹部能量缩的紧紧的紧紧的,心里害怕,感觉不安全不安全。 很不安全很不安全。 我很害怕自己被欺骗被欺骗。 我很害怕...

  • LocalDateTime

    SimpleDateFormat 线程不安全 SimpleDateFormat format方法是线程不安全的,源...

  • 怎么样才安全?

    有点害怕了,出外吃烧烤不安全,住酒店不安全,回家也不安全。那到底怎么样才能安全呢? 接连看到两则关于女性安全的消息...

  • 箴言

    安全和健康 一,安全 安全是存在的首要条件 不安全的地方不要去 不安全的事情不要做 有预见性的远离一切不安全因素,...

  • 操作系统2.25

    不敢借 不安全 系统处于安全状态 ,一定不会发生死锁系统处于不安全状态 ,有可能会发生死锁 处于不安全状态 未必就...

  • iOS多线程到底不安全在哪里?

    iOS多线程到底不安全在哪里? iOS多线程到底不安全在哪里?

  • Python中的一个糟糕的Web应用程序

    一、不安全的Web程序示例。 下面展示一个不安全的Web应用程序。 这个代码采用了Flask框架,但是不安全的原因...

网友评论

      本文标题:Collection-List 安全VS不安全

      本文链接:https://www.haomeiwen.com/subject/xtpvdqtx.html