List接口的大小可变数组的实现。实现了所有可选列表操作,并允许包括null在内的所有元素。除了实现List接口外,此类还提供一些方法来操作内部用来存储列表的数组的大小。(此类大致上等同于Vector类,除了此类是不同步的。)size、isEmpty、get、set、iterator和listIterator操作都以固定时间运行。add操作以分摊的固定时间运行,也就是说,添加n个元素需要O(n)时间。其他所有操作都以线性时间运行(大体上讲)。与用于LinkedList实现的常数因子相比,此实现的常数因子较低。每个ArrayList实例都有一个容量。该容量是指用来存储列表元素的数组的大小。它总是至少等于列表的大小。随着向ArrayList中不断添加元素,其容量也自动增长。并未指定增长策略的细节,因为这不只是添加元素会带来分摊固定时间开销那样简单。在添加大量元素前,应用程序可以使用ensureCapacity操作来增加ArrayList实例的容量。这可以减少递增式再分配的数量。

注意,此实现不是同步的。

如果多个线程同时访问一个ArrayList实例,而其中至少一个线程从结构上修改了列表,那么它必须保持外部同步。(结构上的修改是指任何添加或删除一个或多个元素的操作,或者显式调整底层数组的大小;仅仅设置元素的值不是结构上的修改。)这一般通过对自然封装该列表的对象进行同步操作来完成。如果不存在这样的对象,则应该使用Collections.synchronizedList方法将该列表“包装”起来。这最好在创建时完成,以防止意外对列表进行不同步的访问:

Listlist=Collections.synchronizedList(newArrayList(...));

此类的iterator和listIterator方法返回的迭代器是快速失败的:在创建迭代器之后,除非通过迭代器自身的remove或add方法从结构上对列表进行修改,否则在任何时间以任何方式对列表进行修改,迭代器都会抛出ConcurrentModificationException。因此,面对并发的修改,迭代器很快就会完全失败,而不是冒着在将来某个不确定时间发生任意不确定行为的风险。

注意,迭代器的快速失败行为无法得到保证,因为一般来说,不可能对是否出现不同步并发修改做出任何硬性保证。快速失败迭代器会尽最大努力抛出ConcurrentModificationException。因此,为提高这类迭代器的正确性而编写一个依赖于此异常的程序是错误的做法:迭代器的快速失败行为应该仅用于检测bug。

如上所示,现在建立一个list集合,一个线程对集合进行写入操作,一个线程进行删除操作

import java.util.ArrayList;

import java.util.Collections;

import java.util.Iterator;

import java.util.List;

import java.util.Random;

public class MyArrayList {

/**

* 创建一个列表,一个线程进行写入,一个线程读取 iterator 和 listIterator 方法返回的迭代器是快速失败的

*/

public void readWrite() {

List nums = new ArrayList();

List synNums = Collections.synchronizedList(nums);

//启动写入线程

new WriteListThread(synNums).start();

//启动删除线程

new DeleteListThread(synNums).start();

}

public static void main(String[] args) {

new MyArrayList().readWrite();

}

}

class WriteListThread extends Thread {

private List nums;

public WriteListThread(List nums) {

super(“WriteListThread”);

this.nums = nums;

}

// 不停写入元素1

public void run() {

while (true) {

nums.add(new Random().nextint(1000));

System.out.println(Thread.currentThread().getName());

}

}

}

class DeleteListThread extends Thread {

private List nums;

public DeleteListThread(List nums) {

super(“DeleteListThread”);

this.nums = nums;

}

// 删除第一个元素

public void run() {

while (true) {

try{

System.out.println(Thread.currentThread().getName()+”:”+nums.remove(0));

}

catch(Exception e){

continue ;

}

}

}

}

通过ListsynNums=Collections.synchronizedList(nums);就能对原子操作进行同步了,但是官方api示例为什么要自己手动添加同步呢?

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

synchronized(list) {

Iterator i = list.iterator(); // Must be in synchronized block

while (i.hasNext())

foo(i.next());

}

查看Collections.synchronizedList的源代码

SynchronizedCollection(Collection c) {

if (c==null)

throw new NullPointerException();

this.c = c;

mutex = this;

}

import java.util.ArrayList;

import java.util.Collections;

import java.util.Iterator;

import java.util.List;

import java.util.Random;

public class MyArrayList {

/**

* 创建一个列表,一个线程进行写入,一个线程读取 iterator 和 listIterator 方法返回的迭代器是快速失败的

*/

public void readWrite() {

List nums = new ArrayList();

List synNums = Collections.synchronizedList(nums);

//启动写入线程

new WriteListThread(synNums).start();

//启动删除线程

new DeleteListThread(synNums).start();

}

public static void main(String[] args) {

new MyArrayList().readWrite();

}

}

class WriteListThread extends Thread {

private List nums;

public WriteListThread(List nums) {

super("WriteListThread");

this.nums = nums;

}

// 不停写入元素1

public void run() {

while (true) {

nums.add(new Random().nextint(1000));

System.out.println(Thread.currentThread().getName());

}

}

}

class DeleteListThread extends Thread {

private List nums;

public DeleteListThread(List nums) {

super("DeleteListThread");

this.nums = nums;

}

// 删除第一个元素

public void run() {

while (true) {

try{

System.out.println(Thread.currentThread().getName()+":"+nums.remove(0));

}

catch(Exception e){

continue ;

}

}

}

}

可见对于集合同步操作,使用Collections的同步包装工具类,还需要对非原子操作用户还需要手动进行同步

如下所示,加一个线程,对集合进行读取

class ReadListThread extends Thread {

private List nums;

public ReadListThread(List nums) {

super(“ReadListThread”);

this.nums = nums;

}

// 不停读取元素,非原子操作,则需要手动加上锁

public void run() {

while (true) {

//休眠,将锁交给其他线程

try {

Thread.sleep(1000);

}

catch (InterruptedException e1) {

e1.printStackTrace();

}

synchronized (nums) {

if (nums.size() > 100) {

Iterator iter = nums.iterator();

while (iter.hasNext()) {

System.out.println(Thread.currentThread().getName()

+ ”:” + iter.next());

;

}

} else{

try {

nums.wait(1000);

}

catch (InterruptedException e) {

e.printStackTrace();

}

}

}

}

}

}

总结

以上就是本文关于java集合框架线程同步代码详解的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站其他相关专题,如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!

java 线程同步的list_java集合框架线程同步代码详解相关推荐

  1. java集合框架史上最详解(list set 以及map)

    title: Java集合框架史上最详解(list set 以及map) tags: 集合框架 list set map 文章目录 一.集合框架总体架构 1.1 集合框架在被设计时需满足的目标 1.2 ...

  2. java语言链栈_Java语言实现数据结构栈代码详解

    近来复习数据结构,自己动手实现了栈.栈是一种限制插入和删除只能在一个位置上的表.最基本的操作是进栈和出栈,因此,又被叫作"先进后出"表. 首先了解下栈的概念: 栈是限定仅在表头进行 ...

  3. java redis 断线重连_redis断线重连代码详解

    redis断线重连代码详解 发布时间:2020-05-08 17:59:39 来源:亿速云 阅读:459 作者:Leah redis断线怎么重连?这个问题可能是我们日常工作经常遇到的.本篇文章主要探讨 ...

  4. java 8 两个list_java集合框架综述

    一.集合框架图 简化图: 说明:对于以上的框架图有如下几点说明 1.所有集合类都位于java.util包下.Java的集合类主要由两个接口派生而出:Collection和Map,Collection和 ...

  5. java集合框架的接口_Java集合框架之Collection接口详解

    Java是一门面向对象的语言,那么我们写程序的时候最经常操作的便是对象了,为此,Java提供了一些专门用来处理对象的类库,这些类库的集合我们称之为集合框架.Java集合工具包位于Java.util包下 ...

  6. 集合框架之ArrayDeque类详解

    Java集合框架分析(Deque)---ArrayDeque类详解 目录 一.数据结构 二.类标题 三.字段 四.构造函数 五.方法分析 类型 方法 作用 添加元素 public void addFi ...

  7. Java设计模式之模板方法模式(UML类图分析+代码详解)

    大家好,我是一名在算法之路上不断前进的小小程序猿!体会算法之美,领悟算法的智慧~ 希望各位博友走过路过可以给我点个免费的赞,你们的支持是我不断前进的动力!! 加油吧!未来可期!! 本文将介绍java设 ...

  8. java语言写购物车_JavaWeb后台购物车类实现代码详解

    相信大家肯定都在电商网站买过东西,当我们看中一件喜欢又想买的东西时,这时候你又不想这么快结账,这时候你就可以放入购物车: 就像我们平时去超市买东西一样,会推着购物车去买东西: 那么我们接下来看看jav ...

  9. Java设计模式之组合模式(UML类图分析+代码详解)

    大家好,我是一名在算法之路上不断前进的小小程序猿!体会算法之美,领悟算法的智慧~ 希望各位博友走过路过可以给我点个免费的赞,你们的支持是我不断前进的动力!! 加油吧!未来可期!! 本文将介绍java设 ...

最新文章

  1. bootstraptable 汇总_JS组件系列——表格组件神器:bootstrap table
  2. 关于python的一些好的书籍推荐-推荐几本对于Python初学者比较好的书籍(内含PDF)...
  3. Android ListView重写Adapter
  4. 用Android Studio开发Java App (Runnable Jar)
  5. 关于接口测试的一些总结
  6. 手机可以实现利用putty来管理Linux服务器
  7. RouterOS 动态IP接入上网设置教程(超详细)
  8. java中根据秒生成cron表达式_在线Cron表达式生成器
  9. BZOJ3717: [PA2014]Pakowanie
  10. Bochs、虚拟软盘与BootLoader
  11. java中spilt()方法解释
  12. MISRA C (3)
  13. Springboot毕设项目校园二手交易平台x9zo8java+VUE+Mybatis+Maven+Mysql+sprnig)
  14. 华为副总裁鸿蒙,华为副总裁霸气官宣!鸿蒙系统更新机型再次更新:3月31日全新推送升级...
  15. 手把手教你如何快速制作电子书
  16. 一些经典但惊人的知识
  17. python自动投递简历_python selenium 实现简历自动刷新
  18. 【linux】开关超线程
  19. Acunetix Web Vulnerability Scanner使用指导书
  20. 基于Kafka+ELK搭建海量日志平台

热门文章

  1. 交换机工作原理及MAC表(超详细,秒懂)
  2. 2022.11.21办公自动化 自动发送邮件
  3. dsp广告和信息流广告区别_信息流、DSP、联盟广告、SEM有什么区别?
  4. linux不定循环语法,shell 循环
  5. springboot 秒杀系统(一)
  6. python定义一个列表存放52张扑克牌_Python 制作一副扑克牌,有趣的案例!
  7. classloader读取配置文件_类加载器加载配置文件的几种写法
  8. 腾讯会议突然中断,录制的视频怎么恢复。如何找到腾讯会议保存的视频,腾讯会议怎样录制视频
  9. AttributeError: module ‘labelme.utils‘ has no attribute ‘draw_label‘
  10. 基于MATLAB的数字图像处理系统