java容器

来源:互联网 发布:mac删掉windows 编辑:程序博客网 时间:2024/06/05 02:21
/**
* 容器  concurrent(并发)
* 1:ConcurrentMap(两个实现类,ConcurrentHashMap和ConcurrentSkipListMap)
* Map<Stirng,String> map = new ConcurrentHashMap<>();
* 也是加锁的,在多线程的条件下,效率要比HashMap高一些;在往里面插数据的时候,他把这个容器分成了16段,每一次往
* 里面插得时候,只锁定16段中的一个(16是比较通用的,可以配),就是把这个锁给细化了;两个线程就可以同时并发的往里面插数据,就不需要锁定整个对象了
*
* Map<String,Stirng> map = new ConcurrentSkipListMap<>();
* 跳表map,高并发且排序,往里面插入数据时效率较低,因为是排好顺序的,但是查的效率很高
* Map<String,String> map = new HashMap<>();
* 哈希表实现的,不加锁
* Map<String,String> map = new HshTable<>();
* 加锁的,效率较低,往里面加数据的时候需要锁定整个对象
* Map<String,String> map = new TreeMap<>();
* 由树实现的,排好熟顺序的,不加锁

* 小结:map/set的选择使用 (set和map本质上是一样的,只不过map装了key,value,而set只装了key)
* 不加锁:hashmap,treemap,linkedhashmap
* 加锁:并发不是特别高的情况下:Hashtable,Collections.synchronizedXXX(传入一个不加锁的map,传出一个加锁的map), 
* 例如:List<String> str = new ArrayList<String>(); 创建一个不加锁的Arraylist
* List<String> strSyn = Collections.synchronizedList(str);返回一个加锁的list
* 并发量比较高:concurrentHashmap(读写都加锁)
* 并发量比较高且需要排序:ConcurrentSkipListMap
*/
/**
* 写时复制容器 copyOnWriteArrayList (List的实现类)
* 多线程环境下,写时效率非常低,读时效率高,适合写少读多的环境
* 原理:当往这个容器里面添加元素的时候,他会把这个容器复制一份,在复制的容器后面加一个新的元素,然后把这个引用
* 加到这个新的容器上面,好处是:对于那些从里往外读数据的时候再也不用加锁了
* 适用于:事件监听器 
*/
/**Queue两个子接口:BlockingQueue(阻塞队列)和Deque(双端队列)
* Queue在高并发的情况下可以使用两种队列 1:ConcurrentLinkedQueue 内部加锁(实现类)   
*  2:BlockingQueue阻塞式队列(子接口),两个实现类(LinkedBlockingQueue,ArrayBlockingQueue)
* Queue<String> strs = new ConcurrentLinkedQueue<String>();
* 方法1:strs.offer("aa");往里面加数据,但是他有一个返回值boolean,可以判断值加没加成功//如果用add方法可能会出一些问题,可能有容量的限制,但是offer不会抛异常
* 方法2:strs.poll();拿出第一个元素,然后删掉它
* 方法3:strs.peek();拿出第一个元素,但是不删
/**BlockingQueue的实现类LinkedBlockingQueue
* 无界队列:没有界限,你往里面扔多少个元素都可以,什么时候内存满了什么时候可以。LinkedBlockingQueue阻塞式容器(可实现消费者和生产者模式)
* BlockingQueue<String> strs = new LinkedBlockingQueue<String>();
* 方法1:strs.put("aaa");put如果满了,就会等待 
* 方法2:strs.take();如果空了,就会等待
*/
/**BlockingQueue的实现类 ArrayBlockingQueue
* 有界队列:队列里面能装的元素的个数是固定的
* BlockingQueue<String> strs = new ArrayBlockingQueue<String>(10);
* 如果用put()方法在满了的情况下继续往里面加数据,程序不会停止 ,满了会阻塞,程序阻塞
* 如果用add()方法在满了的情况下继续往里面加数据,就会报异常
* 如果用offer()方法在满了的情况下继续往里面加数据,不会报异常,但是不会把最会一个元素加进去,可通过返回值判断
* strs.offer("aaa",1,TimeUnit.SECONDS);1S钟之后加不进去就不往里面加了
*/
/**BlockingQueue的实现类DelayQueue
* 必须实现Delayed接口,执行定时任务
* DelayQueue:无界队列,加进去的每一个元素(理解成一个任务),这个元素什么时候可以让让消费者往外拿呢?只有等一段时间之后才可以,每一个元素记载着自己还有多长时间可以被消费者拿走;默认是排好顺序的,等待时间最长的先往外拿
* BlockingQueue<String> tasks = new DelayQueue<String>(10);
*/
/**jdk1.7以后才有的
* TransferQueue (transfer转移)用在更多的高并发情况下;无界队列
* LinkedTransferQueue<String> strs = new LinkedTransferQueue<String>();
* 提供了一个特殊的方法 strs.transfer("aaa");
* 消费者先启动,生产者生产完并不是往队列里面扔,而是先去找消费者,如果有消费者,不往队列里面扔了,直接扔给消费者
*  如果生产者先启动,这个时候找不到消费者,他就会阻塞
*  如果用put()和add()和offer()都没问题,因为他容量不为0
*/
/**BlockingQueue的实现类SynchronousQueue
* SynchronousQueue同步队列,特殊的transferQueue;容量为0;无界队列
* BlockingQueue<String> tasks = new SynchronousQueue<>();
*  生产的任何东西,必须的消费者必须马上给我消费掉,不消费掉就会出问题
*  如果用add()就会报错
*  如果用put()没事,应为它阻塞等待消费者消费
*/
/**
* 在使用队列的情况下
* 不同步 ArrayList,LinkedList;同步且并发量较高:vector,Collections.synchronizedXXX
* copyOnWriteArrayList 写的时候非常少,读的时候非常多
* 同步且并发量较高:Queue
* 1:ConcurrentLinkedQueue 高并发情况下的队列
* 2:BlockingQueue 阻塞式队列
* LinkedBlockingQueue 无界队列
* ArrayBlockingQueue 有界队列
* TransferQueue 直接扔给消费者,没有消费者就阻塞
* SynchronousQueue 特殊的TransferQueue,容量为0
* DelayQueue 执行定时任务
*/