Java多线程系列五——列表类

参考资料:

http://xxgblog.com/2016/04/02/traverse-list-thread-safe/

一些列表类及其特性

 类 线程安全 Iterator 特性 说明
Vector fail-fast 内部方法用synchronized修饰,因此执行效率较低
1. 线程安全的列表类并不意味着调用它的代码就一定线程安全

2. 只有CopyOnWriteArrayList能支持在遍历时修改列表元素

ArrayList fail-fast 在多线程环境中使用不当易出错
Collections.synchronizedList fail-fast Collections.synchronizedList可以得到线程安全的列表,与Vector类似
CopyOnWriteArrayList fail-safe 每个线程先复制一份并把地址指向新list,在新的list上操作,因此最终结果未必符合预期,适用于经常需要遍历但很少修改的场景

以下代码模拟多线程环境下,各个类Iterator机制的表现

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Vector;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CountDownLatch;

/**
 * http://xxgblog.com/2016/04/02/traverse-list-thread-safe/
 *
 * @Description: 多线程操作列表
 */
public class ThreadListTest {
    public void multipleThreadArrayList(final List<Integer> list) throws InterruptedException {
        int count = 10;
        for (int i = 0; i < count; i++) {
            list.add(i);
        }
        CountDownLatch countDownLatch = new CountDownLatch(2);
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                for (Integer integer : list) {
                    System.out.println(integer);
                }
                countDownLatch.countDown();
            }
        }).start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getId() + " remove " + list.remove(0));
                countDownLatch.countDown();
            }
        }).start();
        countDownLatch.await();
    }

    public static void main(String[] args) throws InterruptedException {
        ThreadListTest test = new ThreadListTest();
        List<Integer> list;
        list = new Vector<>();// Vector只保证内部方法线程安全
        list = new ArrayList<>();// ArrayList效率较Vector,但非线程安全
        list = Collections.synchronizedList(new ArrayList<>());// Collections.synchronizedList与Vector有异曲同工之妙
        list = new CopyOnWriteArrayList<>();// CopyOnWriteArrayList线程安全:每个线程先复制一份并把地址指向新list,在新的list上操作,因此最终结果未必符合预期

        test.multipleThreadArrayList(list);
        System.out.println(list.toString());
    }
}
时间: 2024-12-21 02:49:03

Java多线程系列五——列表类的相关文章

Java多线程系列十——BlockingQueue类

参考资料:http://ifeve.com/java-synchronousqueue/http://www.cnblogs.com/jackyuj/archive/2010/11/24/1886553.htmlhttp://ifeve.com/java-blocking-queue/ BlockingQueue的几个API认识 方法 说明 add(E e) 添加元素,超出队列size上限后抛异常 offer(E e) 添加元素,超出队列size上限后抛异常,相比add官方更建议使用offer方

Java多线程系列一——Atomic类

参考资料:https://fangjian0423.github.io/2016/03/16/java-AtomicInteger-analysis/http://www.cnblogs.com/549294286/p/3766717.html 最近面试遇到一道编程题,要求两个线程交替打印[0,100]的数字,其中一个只打印奇数,另一个只打印偶数,并且给出特别明显的提示AtomicInteger,当时我在想简直是送分题啊,但事后回想由于手写又没有记得所有API,很多地方不完美,所以面试官最后让我

Java多线程系列二——Thread类的方法

Thread实现Runnable接口并实现了大量实用的方法 public static native void yield(); 此方法释放CPU,但并不释放已获得的锁,其它就绪的线程将可能得到执行机会,它自己也有可能再次得到执行机会 public static native void sleep(long millis) throws InterruptedException; 此方法释放CPU,但并不释放已获得的锁,其它就绪的线程将得到执行机会,在休眠时间结束后,当前线程继续执行 publi

Java多线程系列

参考资料: http://www.jianshu.com/p/40d4c7aebd66 0.环境 Java: jdk1.8.0_91 CPU: Intel Core i5-6500 Memory: 8G 1.说明 本系列文章为Java多线程的学习记录 Java多线程系列一--Java实现线程方法 Java多线程系列二--Thread类的方法 Java多线程系列三--实现线程同步的方法 Java多线程系列四--控制线程执行顺序 Java多线程系列五--列表类 Java多线程系列六--Map实现类

Java多线程系列--“JUC锁”11之 Semaphore信号量的原理和示例

概要 本章,我们对JUC包中的信号量Semaphore进行学习.内容包括:Semaphore简介Semaphore数据结构Semaphore源码分析(基于JDK1.7.0_40)Semaphore示例 转载请注明出处:http://www.cnblogs.com/skywang12345/p/3534050.html Semaphore简介 Semaphore是一个计数信号量,它的本质是一个"共享锁". 信号量维护了一个信号量许可集.线程可以通过调用acquire()来获取信号量的许可

Java多线程系列--“JUC锁”02之 互斥锁ReentrantLock

ReentrantLock介绍 ReentrantLock是一个可重入的互斥锁,又被称为"独占锁". 顾名思义,ReentrantLock锁在同一个时间点只能被一个线程锁持有:而可重入的意思是,ReentrantLock锁,可以被单个线程多次获取.ReentrantLock分为"公平锁"和"非公平锁".它们的区别体现在获取锁的机制上是否公平."锁"是为了保护竞争资源,防止多个线程同时操作线程而出错,ReentrantLock在

Java 多线程(五) 多线程的同步

Java 多线程(五) 多线程的同步 为什么要引入同步机制 在多线程环境中,可能会有两个甚至更多的线程试图同时访问一个有限的资源.必须对这种潜在资源冲突进行预防. 解决方法:在线程使用一个资源时为其加锁即可. 访问资源的第一个线程为其加上锁以后,其他线程便不能再使用那个资源,除非被解锁. 程序实例 用一个取钱的程序例子,来说明为什么需要引入同步. 在使用同步机制前,整体程序如下: public class FetchMoneyTest { public static void main(Stri

Java多线程系列--“JUC锁”05之 非公平锁

获取非公平锁(基于JDK1.7.0_40) 非公平锁和公平锁在获取锁的方法上,流程是一样的:它们的区别主要表现在"尝试获取锁的机制不同".简单点说,"公平锁"在每次尝试获取锁时,都是采用公平策略(根据等待队列依次排序等待):而"非公平锁"在每次尝试获取锁时,都是采用的非公平策略(无视等待队列,直接尝试获取锁,如果锁是空闲的,即可获取状态,则获取锁).在前面的"Java多线程系列--"JUC锁"03之 公平锁(一)&q

java多线程系列(三)

等待通知机制 前言:本系列将从零开始讲解java多线程相关的技术,内容参考于<java多线程核心技术>与<java并发编程实战>等相关资料,希望站在巨人的肩膀上,再通过我的理解能让知识更加简单易懂. 目录 认识cpu.核心与线程 java多线程系列(一)之java多线程技能 java多线程系列(二)之对象变量的并发访问 java多线程系列(三)之等待通知机制 java多线程系列(四)之ReentrantLock的使用 非等待通知 public void run() { try {