并发类容器

本文介绍了JDK提供的并发容器如ConcurrentHashMap、CopyOnWriteArrayList等,并探讨了它们如何提高多线程环境下的应用程序性能。此外,还介绍了几种常见的并发队列及其实现原理,并讨论了Feture、Master-Worker和生产者-消费者模型等多线程设计模式。
摘要由CSDN通过智能技术生成
并发类容器:
    jdk5.0以后提供了很多并发类容器来替换同步类容器二改善性能,同步类容器的状态都是串行化的,他们虽然实现了线程安全,但是严重降低了并发性,在多线程环境时,严重降低了应用程序的吞吐量。
    并发类容器是专门针对并发设计的,使用ConcurrentHashMap来代替给予散列的传统的hashTable,而且在ConcurrentHashMap中,添加了一些常见复合操作的支持,以及使用了CopyOnWriteArrayList来代替Voctor,并发的CopyOnWriteArraySet,以及并发的Queue,ConcurrentLinkedQueue和LinkedBlockingQueue、PriorityBlockingQueue、SynchronousQueue等。


    1.ConcurrentMap借口下面有两个重要的实现:
    ConcurrentHashMap
    ConcurrentSkipListMap(支持并发的排序功能,弥补ConcurrentHashMap)
ConcurrentHashMap内部使用段(Segment)来表示这些不同的部分,每一个段其实就是一个小的Hashtable,他们有自己的锁,只要多个修改操作发生在不同的段上,他们就可以并发进行,把一个整体的部分分成16个段,也就是最高支持16个线程的并发操作修改操作。这也是在多线程场景时减小锁的粒度从而降低锁的竞争一种方案。并且代码中大多数共享变量使用volatile关键字声明,目的是第一时间获取修改的内容,性能非常好;
    2.Copy-On-Write简称COW,是一种用于程序设计中的优化策略。
      JDK里面的COW容器有两种,可以在非常多的并发场景中使用到。
      Copy-On-Write容器既可以写时复制的容器,通俗的理解是当我们往一个容器添加元素时候,不直接往当前容器添加,而是先将当前容器进行copy,复制出一个新的容器,然后在新的容器里面添加元素,添加完成以后,再将原容器的引用指向新的容器,这样做的好处是我们可以对CopyOnWrite容器进行并发的读,而不需要枷锁,因为当前容器不会添加任何元素。所以CopyOnWrite容器也是一种读写分离的思想。读和写不同的容器。
    3.在并发队列上JDK提供了两套实现,一个是以ConcurrentLinkedQueue为代表的高性能队列,一个是以BlockingQueue接口为代表的阻塞队列,无论哪种都继承自Queue;
    ConcurrentLinkedQueue是一个适用于高并发场景下的队列,通过无锁的方式,实现了高并发状态下的高性能,通常ConcurrentLinkedQueue性能好于BlockingQueue。他是一个基于链接节点的无界线程安全队列,该队列的元素遵循先进先出的原则。头是最先加入的,尾是最近加入的。该队列不允许null元素;
    ConcurrentLinkedQueue重要方法:
    add() / offer() 都是加入元素的方法(在ConcurrentLinkedQueue中,这两个方法是没有区别得)
     poll() / peek() 都是取头元素的节点,区别在于前者会上删除元素,后者不会;


   ArrayBlockingQueue:基于数组的阻塞队列实现,在ArrayBlockingQueue内部,维护了一个定长数组,以便缓存队列中的数据对象,其内容都没有实现读写分离,也就是意味着生产和消费不能完全并行,长度是需要定义的,可以指定先进先出或者先进后出,也叫做有界队列,在很多场合非常适合使用;
   LinkedBlockingQueue 基于链表的阻塞队列,同ArrayBlockingQueue类似,其内部也维持着一个数据缓冲队列(该队列由一个链表构成),LinkedBlockingQueue之所以能够高效的处理并发数据,是因为其内部实现采用分离锁(读写分离两个锁),从而实现生产者和消费者的完全并行运行,也是一个无界的队列,
   PriorityBlockingQueue 基于优先级的阻塞队列(优先级的判断通过构造函数传入的Compator对象来决定,也就是说传入队列的对象必须实现Comparable接口),在实现PriorityBlockingQueue时内部控制线程同步的锁采用的是公平锁,他也是一个无界的队列;
   SynchronusQueue 一种没有缓冲的队列,生产者生产的数据会直接被消费者获取并取消;


   4.多线程的设计模式
    并行设计模式属于设计优化的一部分,他是对一些常用的多线程总结和抽象,与穿行程序相比,并行程序的结构通常更为复杂,因此合理的使用并行模式再多线程并发中更具有意义,在这里我们主要介绍Feture、Master-Worker和生产者-消费者模型;

    Feture模式:相当于我们发送Ajax请求的时候,页面是异步的进行后台处理,用户无需一直等待请求的结果,可以继续浏览或者操作其他的内容;



具体的实现代码如下:

  package com.taikang.demo01;




public class Main {


public static void main(String[] args) {
FutureClient client = new FutureClient();
Data data = client.request("我是请求参数");
System.out.println("请求发送成功!!!");
System.out.println("做其他的事情。。。。。。");

String result = data.getRequest();
System.out.println(result);
}
}


package com.taikang.demo01;


public class FutureClient {

public Data request(final String queryStr){
//1.我想要一个代理对象(Data接口的实现类),先返回给我发送请求的客户端,告诉他请求已经接收到,可以做其他的事情
final FutureData futureData = new FutureData();

//2.启动一个线程,去加载其他的真是数据,传递给这个代理对象;
new Thread(new Runnable() {

@Override
public void run() {
//3.这个新的线程可以去偷偷的加载真实的对象然后传递给真实的对象;
RealData data = new RealData(queryStr);
futureData.setRealData(data);
}
}).start();
return futureData;
}
}


package com.taikang.demo01;


public class RealData implements Data{

private String result;

public RealData (String queryStr){
System.out.println("根据" + queryStr + "进行查询,这是一个很耗时间的操作。。。。");

try {
Thread.sleep(5000);
} catch (Exception e) {
}
System.out.println("操作完成,获取到结果");
result = "我是查询结果";
}

@Override
public String getRequest() {
return result;
}
}



package com.taikang.demo01;


public class FutureData implements Data{
private RealData realData;

private boolean isReady = false;

public synchronized void setRealData(RealData realData){
//如果已经加载完毕了,直接返回
if (isReady) {
return;
}
//如果没有,就加载真实的对象;
this.realData = realData;
isReady = true;

//进行通知
notify();
}
@Override
public synchronized String getRequest() {
while(!isReady){
try {
wait();
} catch (Exception e) {
}
}

return this.realData.getRequest();
}
}


package com.taikang.demo01;


public interface Data {
String getRequest();
}



package com.taikang.demo01;


public class RealData implements Data{

private String result;

public RealData (String queryStr){
System.out.println("根据" + queryStr + "进行查询,这是一个很耗时间的操作。。。。");

try {
Thread.sleep(5000);
} catch (Exception e) {
}
System.out.println("操作完成,获取到结果");
result = "我是查询结果";
}

@Override
public String getRequest() {
return result;
}
}


5.


5.


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值