非阻塞线程安全列表——ConcurrentLinkedDeque应用举例

转载自  非阻塞线程安全列表——ConcurrentLinkedDeque应用举例

 

 在java中,最常用的数据结构可能是列表。有数目不详的元素列表,你可以添加、阅读、或删除任何位置的元素。此外,并发列表允许不同的线程列表中添加或删除元素时不产生任何数据不一致。非阻塞列表提供如下操作,如果操作不能立即完成,列出抛出异常或者返回一个null值。Java 7中引入了ConcurrentLinkedDeque类,它实现了一个非阻塞并发列表,在本教程中,我们将学习使用这个类。

 

       在这个例子中,我们将实现一个示例使用以下两个不同的任务:

       一个将大量数据添加到一个列表中
       一个大量地从同样的列表中删除数据
      让我们为每个任务创建的线程:

package com.howtodoinjava.demo.multithreading.concurrentLinkedDequeExample;  import java.util.concurrent.ConcurrentLinkedDeque;  public class AddTask implements Runnable {  private ConcurrentLinkedDeque<String> list;  public AddTask(ConcurrentLinkedDeque<String> list) {  this.list = list;  }  @Override  public void run() {  String name = Thread.currentThread().getName();  for (int i = 0; i < 10000; i++) {  list.add(name + ": Element " + i);  }  }  
}  

和:

packagecom.howtodoinjava.demo.multithreading.concurrentLinkedDequeExample;importjava.util.concurrent.ConcurrentLinkedDeque;publicclass RemoveTask implementsRunnable {privateConcurrentLinkedDeque<String> list;publicRemoveTask(ConcurrentLinkedDeque<String> list) {this.list = list;}@Overridepublicvoid run() {for(inti = 0; i < 5000; i++) {list.pollFirst();list.pollLast();}}
}

 现在,让我们创建100个线程将数据添加到列表和100个线程从列表删除数据。如果真的是线程安全的和非阻塞,它会几乎立即给你最终结果。此外,列表大小最终将是零。

package com.howtodoinjava.demo.multithreading.concurrentLinkedDequeExample;  import java.util.concurrent.ConcurrentLinkedDeque;  public class Main {  public static void main(String[] args)  {  ConcurrentLinkedDeque<String> list = new ConcurrentLinkedDeque<>();  Thread threads[] = new Thread[100];  for (int i = 0; i < threads.length; i++) {  AddTask task = new AddTask(list);  threads[i] = new Thread(task);  threads[i].start();  }  System.out.printf("Main: %d AddTask threads have been launched\n", threads.length);  for (int i = 0; i < threads.length; i++) {  try {  threads[i].join();  } catch (InterruptedException e) {  e.printStackTrace();  }  }  System.out.printf("Main: Size of the List: %d\n", list.size());  for (int i = 0; i < threads.length; i++) {  RemoveTask task = new RemoveTask(list);  threads[i] = new Thread(task);  threads[i].start();  }  System.out.printf("Main: %d RemoveTask threads have been launched\n", threads.length);  for (int i = 0; i < threads.length; i++) {  try {  threads[i].join();  } catch (InterruptedException e) {  e.printStackTrace();  }  }  System.out.printf("Main: Size of the List: %d\n", list.size());  }  
} 

Output:  
Main: 100 AddTask threads have been launched  
Main: Size of the List: 1000000  
Main: 100 RemoveTask threads have been launched  

Main: Size of the List: 0  

 

 

让我们看看它如何工作:

  1. 首先,你执行100个 AddTask任务将元素添加到任务列表。每一个任务使用 add()方法插入10000个元素到列表,新增加的元素都会放到列表最后。当所有这些任务已经完成了,你会在控制台打印出了列表的元素数量。这时,这个列表有1000000个元素。
  2. 然后,你执行100个 RemoveTask任务将元素从列表中删除。每一个任务删除这个列表 用pollFirst()pollLast()方法。pollFirst()方法返回和删除列表的第一个元素和pollLast()方法返回和删除最后一个元素的列表。如果列表为空,这些方法返回一个null值。当所有这些任务已经完成了,在控制台的打印出列表中元素的数量,这时,有零元素列表。
  3. 打印列表的元素的数量时,你使用了 size()方法,你必须考虑,这种方法并不是真实的,特别是如果你使用它在线程进行列表中添加同时又删除数据。计数的方法遍历整个列表的元素和内容列表可以改变这个操作。一旦在你使用它们时没有任何线程修改列表,你可以保证返回的结果是正确的。

请注意, ConcurrentLinkedDeque类提供了更多的方法来获取元素列表形式:

  • getFirst() getLast():这些方法返回分别从列表中第一个和最后一个元素。他们不会从列表中删除返回的元素。如果列表是空的,这些方法抛出一个 NoSuchElementExcpetion例外。
  • peek(), peekFirst(), peekLast():这些方法返回列表的第一个和最后一个元素。他们不会从列表中删除返回的元素。如果列表为空,这些方法返回一个null值。
  • remove(), removeFirst(), removeLast():这些方法返回列表的第一个和最后一个元素。他们从列表中移除返回的元素。如果列表是空的,这些方法抛出一个 NoSuchElementException例外。
  • 一个 ConcurrentLinkedDeque是一个合适的选择,许多线程共享访问公共集合。
  • 像大多数其他并发集合实现,这个类不允许null元素的使用。
  • 迭代器是弱一致的,返回元素反映在一些点或双端队列的状态,因为迭代器的创建。他们不把ConcurrentModificationException与其他操作,可以同时进行。

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/327595.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

整合JDBC---SpringBoot

整合JDBC SpringData简介 对于数据访问层&#xff0c;无论是 SQL(关系型数据库) 还是 NOSQL(非关系型数据库)&#xff0c;Spring Boot 底层都是采用 Spring Data 的方式进行统一处理。 Spring Boot 底层都是采用 Spring Data 的方式进行统一处理各种数据库&#xff0c;Sprin…

struts+hibernate+oracle+easyui实现lazyout组件的简单案例——EmpDao层代码

严格按照三层架构来写的&#xff0c;Dao层的代码比较少&#xff0c;我直接把Emp和实现类的都放在这篇文章里面吧&#xff0c; IEmpDao.java接口&#xff1a; /** * Title: IEmpDao.java * Package org.dao * Description: TODO该方法的主要作用&#xff1a; * author A18ccm…

在idea 中添加和删除模块Module

在idea 中添加和删除模块Module ThinkPet 2018-12-22 10:12:50 4125 收藏 1 分类专栏&#xff1a; idea 版权 1.添加模块 2.删除模块 ———————————————— 版权声明&#xff1a;本文为CSDN博主「ThinkPet」的原创文章&#xff0c;遵循CC 4.0 BY-SA版权协议&am…

ASP.NET Core File Providers

ASP.NET Core通过对File Providers的使用实现了对文件系统访问的抽象。 查看或下载示例代码 File Provider 抽象 File Providers是文件系统之上的一层抽象。它的主要接口是IFileProvider。IFileProvider公开了相应方法用来获取文件信息&#xff08;IFileInfo&#xff09;&#…

java并发编程(二十一)----(JUC集合)CopyOnWriteArraySet和ConcurrentSkipListSet介绍

转载自 java并发编程&#xff08;二十一&#xff09;----(JUC集合)CopyOnWriteArraySet和ConcurrentSkipListSet介绍 这一节我们来接着介绍JUC集合&#xff1a;CopyOnWriteArraySet和ConcurrentSkipListSet。从名字上来看我们知道CopyOnWriteArraySet与上一节讲到的CopyOnWrit…

linux u32,如何在程序中使用u32这个类型啊。

如何在程序中使用u32这个类型啊。 我用的keil 4.5#include "stm32f10x.h"int main(void){GPIO_InitTypeDef GPIO_Init1;GPIO_Init1.GPIO_Pin GPIO_Pin_0;GPIO_Init1.GPIO_Speed GPIO_Speed_50MHz;GPIO_Init1.GPIO_Mode GPIO_Mode_Out_PP;GPIO_Init(GPIOA,&GPI…

虚拟机安装CentOS-7-x86_64-DVD-1708说明

https://blog.csdn.net/guanzhuwo/article/details/105903844 镜像已经下载了 使用IDM下载 http://mirrors.aliyun.com/centos/7/isos/x86_64/CentOS-7-x86_64-DVD-2003.iso 虚拟机安装CentOS-7-x86_64-DVD-1708说明 guanzhuwo 2020-05-03 15:12:22 102 收藏 分类专栏&a…

struts+hibernate+oracle+easyui实现lazyout组件的简单案例——DeptDao层代码

下面来看看DeptDao 的事例吧&#xff1a; IDeptDao.java: /** * Title: IDeptDao.java * Package org.dao * Description: TODO该方法的主要作用&#xff1a; * author A18ccms A18ccms_gmail_com * date 2017-4-19 下午6:37:00 * version V1.0 */ package org.dao;impo…

IJ实现侧边栏单独搜索

第一步任意点击一个 第二步输入要搜索的单词

关于全局ID,雪花(snowflake)算法的说明

C#版本的国外朋友已经封装了&#xff0c;大家可以去看看&#xff1a;https://github.com/ccollie/snowflake-net 强大的网友出来个简化版本&#xff1a;http://blog.csdn.net/***/article/details/*** &#xff08;地址我就不贴了&#xff0c;对前辈需要最起码的尊敬&#xff0…

Java并发包:ConcurrentMap

转载自 Java并发包&#xff1a;ConcurrentMap 文章译自&#xff1a;http://tutorials.jenkov.com/java-util-concurrent/index.html 抽空翻译了一下这个教程的文章&#xff0c;后面会陆续放出&#xff0c;如有不妥&#xff0c;请批评指正。 转自请注明出处。 之前漏了一篇文…

SecureCRT的下载、安装( 过程非常详细!!值得查看)

我自己百度联通主号有存储了 可以下下来 有视频加这个文档 就可以了 https://blog.csdn.net/qq_39052513/article/details/100272502 SecureCRT的下载、安装&#xff08; 过程非常详细&#xff01;&#xff01;值得查看&#xff09; 置顶 超Ren专属 2020-06-02 21:29:33 1…

整合Druid---SpringBoot

整合Druid(数据源) Druid简介 Java程序很大一部分要操作数据库&#xff0c;为了提高性能操作数据库的时候&#xff0c;又不得不使用数据库连接池。 Druid 是阿里巴巴开源平台上一个数据库连接池实现&#xff0c;结合了 C3P0、DBCP 等 DB 池的优点&#xff0c;同时加入了日志…

struts+hibernate+oracle+easyui实现lazyout组件的简单案例——工具类

次此篇文章是两个工具类的实现&#xff0c;HibernateUtil.java和分页的工具类PageUtil.java的实现&#xff1a; 先看看HibernateUtil.java的实现&#xff1a; package org.util;import javax.transaction.Transaction;import org.hibernate.Session; import org.hibernate.Sess…

理想的互联网服务后台框架的九个要点

理想的互联网服务后台框架的九个要点对于互联网服务后台团队&#xff0c;开发框架的选择是非常关键的一个问题&#xff0c;多年的海量服务经验和教训使得我们团队深刻的认识到&#xff1a; 要尽早规范团队的开发服务框架&#xff0c;避免到了后期&#xff0c;各种开发语言混杂、…

linux 无线网卡驱动桥转发,引用和完美转发

# 右值引用 移动语意~~~右值引用解决了左值引用无法传递临时对象和常引用传递的对象只读的问题. 右值引用允许传递一个可变的临时对象引用.移动构造使用移动而非赋值语义完成构造过程, 主要用于解决函数返回值时的大量深拷贝开销.#include int main(void){int a 30;int &b…

虚拟机安装centeros7 无法连接网络 virsh命令找不到 删除多余的vir0 不然dubbo会有问题

进入linux ping www.baidu.com 无法访问 cd /etc/sysconfig/network-scripts vi ifcfg-ens33 修改这个文件 onbootyes 原来是on shutdown -h now 关机 然后重启虚拟机 再次ping ping www.baidu.com 就通了 https://www.zhihu.com/question/53708440 virsh命令找…

Java集合之EnumSet

转载自 Java集合之EnumSet EnumSet EnumSet 是一个专为枚举设计的集合类&#xff0c;EnumSet中的所有元素都必须是指定枚举类型的枚举值&#xff0c;该枚举类型在创建EnumSet时显式或隐式地指定。 EnumSet的集合元素也是有序的&#xff0c;EnumSet以枚举值在Enum类内的定义顺…

struts+hibernate+oracle+easyui实现lazyout组件的简单案例——OpSessionview实现

此过滤器的功能就是让Session始终保持着一个打开的状态&#xff1a; /** * Title: OpenSessionFilter.java * Package org.web * Description: TODO该方法的主要作用&#xff1a; * author A18ccms A18ccms_gmail_com * date 2017-4-19 下午6:51:37 * version V1.0 */ pa…

yaml配置文件整合Mybatis易错点

配置 mybatis:type-aliases-package: com.kuang.pojomapper-locations: classpath:mybatis/mapper/*.xml容易写成以下格式导致出错 mybatis:type-aliases-package: com.kuang.pojomapper-locations: classpath: mybatis/mapper/*.xml