当前位置: 首页 > news >正文

软膜做网站有用吗网络事件营销案例

软膜做网站有用吗,网络事件营销案例,附近学电脑在哪里报名,找工作网站一、CopyOnWriteArrayList(一) 1. 简介 并发包中的并发List只有CopyOnWriteArrayList。 CopyOnWriteArrayList是一个线程安全的ArrayList,对其进行的修改操作都是在底层的一个复制的数 组(快照)上进行的&#xff0…

一、CopyOnWriteArrayList(一)

1. 简介

并发包中的并发List只有CopyOnWriteArrayList。

CopyOnWriteArrayList是一个线程安全的ArrayList,对其进行的修改操作都是在底层的一个复制的数

组(快照)上进行的,也就是使用了写时复制策略。

CopyOnWriteArraylist的类图结构如图:

在CopyOnWriteArrayList的类图中,每个CopyOnWriteArrayList对象里面有一个array数组对象用来存放具体元素,ReentrantLock独

占锁对象用来保证同时只有一个线程对array进行修改。

CopyOnWriteArrayList使用写时复制的策略来保证list的一致性,而获取 - 修改 - 写入三步操作并不是原子性的,所以在增删改的过程

中都使用了独占锁,来保证在某个时间只有一个线程能对list数组进行修改。

另外CopyOnWriteArrayList提供了弱一致性的迭代器,从而保证在获取迭代器后,其他线程对list的修改是不可见的,迭代器遍历的数

组是一个快照。

2. 独占锁

独占锁是一种思想: 只能有一个线程获取锁,以独占的方式持有锁。和悲观锁、互斥锁同义。

Java中用到的独占锁: synchronized,ReentrantLock。

3. 弱一致性的迭代器

遍历列表元素可以使用迭代器。在讲解什么是迭代器的弱一致性前,先举一个例子来说明如何使用迭代器:

    public static void main(String[] args) {CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>();list.add("Hello");list.add("World");Iterator<String> iterator = list.iterator();while (iterator.hasNext()) {System.out.println(iterator.next());}}

运行结果:

迭代器的hasNext方法用于判断列表中是否还有元素,next方法则具体返回元素。

好了,下面来看CopyOnWriteArrayList中迭代器的弱一致性是怎么回事,

所谓弱一致性是指返回迭代器后,其他线程对list的增删改对迭代器是不可见的,下面看看这是如何做到的。

在如上代码中,当调用iterator()方法获取迭代器时实际上会返回一个COWIterator对象,COWIterator对象的snapshot变量保存了当

前list的内容,cursor是遍历list时数据的下标。

为什么说snapshot是list的快照呢?

明明是指针传递的引用啊,而不是副本。如果在该线程使用返回的迭代器遍历元素的过程中,其他线程没有对list进行增删改,那么

snapshot本身就是list的array,因为它们是引用关系。但是如果在遍历期间其他线程对该list进行了增删改,那么snapshot就是快照了,

因为增删改后list里面的数组被新数组替换了,这时候老数组被snapshot引用。这也说明获取迭代器后,使用该迭代器元素时,其他线

程对该list进行的增删改不可见,因为它们操作的是两个不同的数组,这就是弱一致性。

示例:演示多线程下迭代器的弱一致性的效果。

public class Atomic {private static final CopyOnWriteArrayList<String> arrayList = newCopyOnWriteArrayList<>();public static void main(String[] args) throws InterruptedException {arrayList.add("hello");arrayList.add("alibaba");arrayList.add("welcome");arrayList.add("to");arrayList.add("hangzhou");Thread threadOne = new Thread(() -> {//修改list中下标为1的元素为babaarrayList.set(1, "baba");//删除元素arrayList.remove(2);arrayList.remove(3);});//保证在修改线程启动前获取迭代器Iterator<String> itr = arrayList.iterator();threadOne.start();// 保证threadOne的run方法执行完毕(完成对arrayList的修改)Thread.sleep(1000);while (itr.hasNext()) System.out.println(itr.next());}
}

运行结果:

在如上代码中,main函数首先初始化了arrayList,然后在启动线程前获取到了arrayList迭代器。

子线程threadOne启动后首先修改了arrayList的第一个元素的值,然后删除了arrayList中下标为2和3的元素。

主线程在子线程执行完毕后使用获取的迭代器遍历数组元素,从输出结果我们知道,在子线程里面进行的操作一个都没有生效,这就是迭

代器弱一致性的体现。

需要注意的是,获取迭代器的操作必须在子线程操作之前进行。

二、CopyOnWriteArrayList(二)

1. 简介

在 ArrayList 的类注释上,JDK 就提醒了我们,如果要把 ArrayList 作为共享变量的话,是线程不安全的,推荐我们自己加锁或者使用

Collections.synchronizedList 方法,其实 JDK 还提供了另外一种线程安全的 List,叫做 CopyOnWriteArrayList

2. 原理

很多时候,我们的系统应对的都是读多写少的并发场景。CopyOnWriteArrayList容器允许并发读,读操作是无锁的,性能较高。至于写

操作,比如向容器中添加一个元素,则首先将当前容器复制一份,然后在新副本上执行写操作,结束之后再将原容器的引用指向新容器。

  • 线程安全的,多线程环境下可以直接使用,无需加锁;
  • 通过锁 + 数组拷贝 + volatile 关键字保证了线程安全;
  • 每次数组操作,都会把数组拷贝一份出来,在新数组上进行操作,操作成功之后再赋值回去。

从整体架构上来说,CopyOnWriteArrayList 数据结构和 ArrayList 是一致的,底层是个数组,只不过 CopyOnWriteArrayList 在对数组进

行操作的时候,基本会分四步走:

  • 加锁;
  • 从原数组中拷贝出新数组;
  • 在新数组上进行操作,并把新数组赋值给数组容器;
  • 解锁

除了加锁之外,CopyOnWriteArrayList 的底层数组还被 volatile 关键字修饰,意思是一旦数组被修改,其它线程立马能够感知到,

代码如下:

private transient volatile Object[] array;

整体上来说,CopyOnWriteArrayList 就是利用锁 + 数组拷贝 + volatile 关键字保证了 List 的线程安全。

3. 优点

读操作(不加锁)性能很高,因为无需任何同步措施,比较适用于读多写少的并发场景。Java的list在遍历时,若中途有别的线程对list容

器进行修改,则会抛ConcurrentModificationException异常。而CopyOnWriteArrayList由于其"读写分离"的思想,遍历和修改操作分别

作用在不同的list容器,所以在使用迭代器进行遍历时候,也就不会抛出ConcurrentModificationException异常了。

4. 缺点

一是内存占用问题,毕竟每次执行写操作都要将原容器拷贝一份。数据量大时,对内存压力较大,可能会引起频繁GC;

二是无法保证实时性,因为CopyOnWrite的写时复制机制,所以在进行写操作的时候,内存里会同时驻扎两个对象的内存,旧的对象和新

写入的对象(注意:在复制的时候只是复制容器里的引用,只是在写的时候会创建新对象添加到新容器里,而旧容器的对象还在使用,所

以有两份对象内存)。

5. 源码分析

添加操作

    public boolean add(E e) {//ReentrantLock加锁,保证线程安全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();}}

添加的逻辑很简单,先将原容器copy一份,然后在新副本上执行写操作,之后再切换引用。当然此过程是要加锁的。

删除操作

    public E remove(int index) {//加锁final ReentrantLock lock = this.lock;lock.lock();try {Object[] elements = getArray();int len = elements.length;E oldValue = get(elements, index);int numMoved = len - index - 1;if (numMoved == 0)//如果要删除的是列表末端数据,拷贝前len-1个数据到新副本上,再切换引用setArray(Arrays.copyOf(elements, len - 1));else {//否则,将除要删除元素之外的其他元素拷贝到新副本中,并切换引用Object[] newElements = new Object[len - 1];System.arraycopy(elements, 0, newElements, 0, index);System.arraycopy(elements, index + 1, newElements, index,numMoved);setArray(newElements);}return oldValue;} finally {//解锁lock.unlock();}}

删除操作同理,将除要删除元素之外的其他元素拷贝到新副本中,然后切换引用,将原容器引用指向新副本。同属写操作,需要加锁。

我们再来看看读操作,CopyOnWriteArrayList的读操作是不用加锁的,性能很高。

    public E get(int index) {return get(getArray(), index);}

直接读取即可,无需加锁

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

弱一致性的迭代器

所谓弱一致性是指返回迭代器后,其他线程对list的增删改查对迭代器是不可见的

// 演示多线程下迭代器的弱一致性结果
public class copylist {private static volatile CopyOnWriteArrayList<String> arrayList = new CopyOnWriteArrayList<>();public static void main(String[] args) throws InterruptedException {arrayList.add("hello");arrayList.add("alibaba");arrayList.add("welcome");arrayList.add("to");arrayList.add("hangzhou");Thread threadOne = new Thread(new Runnable() {@Overridepublic void run() {// 修改list中下标为1的元素为aliarrayList.set(1, "ali");// 删除元素arrayList.remove(2);arrayList.remove(3);}});// 保证在修改线程启动前获取迭代器Iterator<String> itr = arrayList.iterator();// 启动线程threadOne.start();// 等待子线程执行完毕threadOne.join();while(itr.hasNext()) {System.out.println(itr.next());}}
}

执行程序:

hello
alibaba
welcome
to
hangzhouProcess finished with exit code 0

执行程序:

hello
alibaba
welcome
to
hangzhouProcess finished with exit code 0

从输出结果我们知道,在子线程里面进行的操作一个都没有生效,这就是迭代器弱一致性的体现。

需要注意的是,获取迭代器的操作必须在子线程操作之前进行。

6. ArrayList转为线程安全的方法

List list = Collections.synchronizedList(new ArrayList());


文章转载自:
http://cameroun.rbzd.cn
http://conacre.rbzd.cn
http://archway.rbzd.cn
http://euphemia.rbzd.cn
http://odontophorous.rbzd.cn
http://imitative.rbzd.cn
http://diphtheritic.rbzd.cn
http://dragonish.rbzd.cn
http://regelate.rbzd.cn
http://euphonise.rbzd.cn
http://piddock.rbzd.cn
http://codetta.rbzd.cn
http://discern.rbzd.cn
http://eroica.rbzd.cn
http://fut.rbzd.cn
http://inception.rbzd.cn
http://brioche.rbzd.cn
http://barish.rbzd.cn
http://recrystallize.rbzd.cn
http://knitgoods.rbzd.cn
http://raia.rbzd.cn
http://inner.rbzd.cn
http://megaripple.rbzd.cn
http://inebriety.rbzd.cn
http://odysseus.rbzd.cn
http://paraglider.rbzd.cn
http://lotto.rbzd.cn
http://jactation.rbzd.cn
http://coactive.rbzd.cn
http://frse.rbzd.cn
http://camerlingo.rbzd.cn
http://trashy.rbzd.cn
http://hyperspace.rbzd.cn
http://memorabilia.rbzd.cn
http://stop.rbzd.cn
http://scholar.rbzd.cn
http://overdoor.rbzd.cn
http://barnaby.rbzd.cn
http://bcc.rbzd.cn
http://fractography.rbzd.cn
http://maritsa.rbzd.cn
http://midianite.rbzd.cn
http://praam.rbzd.cn
http://strangury.rbzd.cn
http://annotinous.rbzd.cn
http://mi.rbzd.cn
http://thirty.rbzd.cn
http://crenate.rbzd.cn
http://hum.rbzd.cn
http://spinstress.rbzd.cn
http://consular.rbzd.cn
http://bfr.rbzd.cn
http://silicula.rbzd.cn
http://cymous.rbzd.cn
http://sleeveboard.rbzd.cn
http://ley.rbzd.cn
http://unsnarl.rbzd.cn
http://magicube.rbzd.cn
http://mosslike.rbzd.cn
http://newfangle.rbzd.cn
http://datum.rbzd.cn
http://princedom.rbzd.cn
http://word.rbzd.cn
http://notionist.rbzd.cn
http://sacking.rbzd.cn
http://tycooness.rbzd.cn
http://bankrupt.rbzd.cn
http://figwort.rbzd.cn
http://dural.rbzd.cn
http://vampirism.rbzd.cn
http://guinea.rbzd.cn
http://hereinbelow.rbzd.cn
http://welshy.rbzd.cn
http://landman.rbzd.cn
http://thiophenol.rbzd.cn
http://afterhours.rbzd.cn
http://morphophoneme.rbzd.cn
http://dottrel.rbzd.cn
http://adnexa.rbzd.cn
http://belgrade.rbzd.cn
http://mariology.rbzd.cn
http://scioptic.rbzd.cn
http://cruse.rbzd.cn
http://compulsion.rbzd.cn
http://leucine.rbzd.cn
http://languistics.rbzd.cn
http://coper.rbzd.cn
http://indus.rbzd.cn
http://unanimous.rbzd.cn
http://gubernatorial.rbzd.cn
http://standoff.rbzd.cn
http://fanfare.rbzd.cn
http://jacinthe.rbzd.cn
http://forgivingly.rbzd.cn
http://nonscheduled.rbzd.cn
http://slingshot.rbzd.cn
http://heartrending.rbzd.cn
http://acinus.rbzd.cn
http://limpness.rbzd.cn
http://prospector.rbzd.cn
http://www.15wanjia.com/news/94897.html

相关文章:

  • 印度网站建设多少钱深圳网站建设
  • 在静安正规的设计公司网站朋友圈广告投放
  • 做网站的服务器cpu异常选择一个产品做营销方案
  • 苏州网站建设工作室游戏推广员是做什么的
  • 花房姑娘直播关键词优化是怎么弄的
  • 成都建网站的公司百度下载免费安装最新版
  • 富阳做网站百度搜索
  • 织梦响应式网站模板网站编辑seo
  • 湛江网站网站建设谷歌搜索引擎 google
  • 模板做图 网站有哪些uc信息流广告投放
  • 南昌市做网站深圳网络推广培训
  • 营销公司网络检索网站排名seo教程
  • 浏阳网站定制推广网站公司
  • 南上海网站建设游戏推广员怎么做
  • 技术支持 东莞网站建设互联网推广方案
  • 做网站平台公司哪家好离我最近的广告公司
  • 装修公司合作平台的网站百度如何注册公司网站
  • 未央区政府网站建设中小企业网站优化
  • vvic网站一起做网店互联网推广营销
  • 虎门专业网站建设软文是什么意思?
  • 心雨在线高端网站建设最新做做网站
  • 政府网站品牌建设方案千锋教育培训多少钱费用
  • 织梦做电子商务网站百度关键字搜索排名
  • 大连比较好的网站公司吗黄页网络的推广网站有哪些
  • 嘉兴哪家公司做网站比较好的郑州seo服务公司
  • 磐石网站seo网站排名首页
  • jsp网站建设 书籍口碑最好的it培训机构
  • 网络销售促进的方式免费seo网站的工具
  • 菠菜网站模板新闻网最新消息
  • wordpress大前端主题免费试用seo先上排名后收费