文档章节

Java 集合线程安全

Joker上上签
 Joker上上签
发布于 2016/11/10 19:11
字数 1113
阅读 24
收藏 2

线程不安全的的集合有(HashSet,TreeSet,ArrayList,ArrayDeque,LinkedList,HashMap,TreeMap);

线程安全的集合有(Vector,HashTable);

Java给你的保证的线程安全,是说它的方法是执行是排它的,而不是对这个对象本身的多次调用情况下,还是安全的。

1)线程不安全案例:

public class ListThread implements Runnable {  
    String name;  
    List<String> l; 
  
    ListThread(String name, List<String> l) {  
        this.name = name;  
        this.l = l;  
    }  
  
    public void run() {  
        System.out.println(name + "start");  
        for(int i = 0; i<6; i++){
            l.add(name + ".add");  
            System.out.println(name + " list size is " + l.size());  
            try {  
                Thread.sleep(10);  
            } catch(InterruptedException e) {  
                System.out.println(e.getMessage());  
            }  
        }  
    }  
  
    public static void main(String args[]) throws InterruptedException {  
  
        List<String> l = new ArrayList<String>();  
  
        ListThread hello1 = new ListThread("hello1", l);  
        ListThread hello2 = new ListThread("hello2", l);  
        ListThread hello3 = new ListThread("hello3", l);  
  
        Thread h1 = new Thread(hello1);  
        Thread h2 = new Thread(hello2);  
        Thread h3 = new Thread(hello3);  
        h1.start();  
        h2.start();  
        h3.start();  
    }  
}  

执行结果:

hello1start
hello1 list size is 1
hello3start
hello3 list size is 2
hello2start
hello2 list size is 3
hello1 list size is 4
hello3 list size is 5
hello2 list size is 6
hello1 list size is 7
hello2 list size is 9
hello3 list size is 9
hello1 list size is 10
hello3 list size is 11
hello2 list size is 12
hello1 list size is 13
hello3 list size is 14
hello2 list size is 14
hello1 list size is 15
hello3 list size is 17
hello2 list size is 17

----以上结果每个线程执行6次list添加,结果list长度只有17个,数据丢失,线程不安全。

2)线程安全案例:

public class VectorThread implements Runnable {  
    String name;  
    Vector<String> v;  
  
    VectorThread(String name, Vector<String> v) {  
        this.name = name;  
        this.v = v;  
    }  
  
    public void run() {  
        System.out.println(name + "start");  
        for(int i = 0; i<6; i++){
            v.add(name + ".add");  
            System.out.println(name + " vector size is " + v.size());  
  
            try {  
                Thread.sleep(10);  
            } catch(InterruptedException e) {  
                System.out.println(e.getMessage());  
            }  
        }  
    }  
  
    public static void main(String args[]) throws InterruptedException {  
  
        Vector<String> v = new Vector<String>();  
  
        VectorThread hello1 = new VectorThread("hello1", v);  
        VectorThread hello2 = new VectorThread("hello2", v);  
        VectorThread hello3 = new VectorThread("hello3", v);  
  
        Thread h1 = new Thread(hello1);  
        Thread h2 = new Thread(hello2);  
        Thread h3 = new Thread(hello3);  
        h1.start();  
        h2.start();  
        h3.start();  
    }  
}  

执行结果:

hello2start
hello2 vector size is 1
hello3start
hello1start
hello1 vector size is 3
hello3 vector size is 2
hello1 vector size is 5
hello3 vector size is 5
hello2 vector size is 6
hello1 vector size is 7
hello2 vector size is 8
hello3 vector size is 9
hello3 vector size is 12
hello2 vector size is 11
hello1 vector size is 11
hello3 vector size is 14
hello2 vector size is 15
hello1 vector size is 14
hello3 vector size is 17
hello2 vector size is 17
hello1 vector size is 18

--------------线程安全,结果执行无论多少次,最后vector的长度都是18,数据添加完整安全,但是长度在线程抢占时还是有size相同的情况,需要在外围另外添加synchronized

3)外围加锁后的线程安全案例

public class VectorThread2 implements Runnable {  
    String name;  
    Vector<String> v;  
  
    VectorThread2(String name, Vector<String> v) {  
        this.name = name;  
        this.v = v;  
    }  
  
    public void run() {  
        System.out.println(name + "start");  
        
        for(int i = 0; i<6; i++){
        	synchronized(v){
        		v.add(name + ".add");  
        		System.out.println(name + " vector size is " + v.size());  
        	}
            try {  
                Thread.sleep(10);  
            } catch(InterruptedException e) {  
                System.out.println(e.getMessage());  
            }  
        }  
    }  
  
    public static void main(String args[]) throws InterruptedException {  
  
        Vector<String> v = new Vector<String>();  
  
        VectorThread2 hello1 = new VectorThread2("hello1", v);  
        VectorThread2 hello2 = new VectorThread2("hello2", v);  
        VectorThread2 hello3 = new VectorThread2("hello3", v);  
  
        Thread h1 = new Thread(hello1);  
        Thread h2 = new Thread(hello2);  
        Thread h3 = new Thread(hello3);  
        h1.start();  
        h2.start();  
        h3.start();  
    }  
}  

执行结果:

hello2start
hello2 vector size is 1
hello2 vector size is 2
hello2 vector size is 3
hello2 vector size is 4
hello1start
hello1 vector size is 5
hello2 vector size is 6
hello1 vector size is 7
hello2 vector size is 8
hello1 vector size is 9
hello3start
hello3 vector size is 10
hello1 vector size is 11
hello3 vector size is 12
hello1 vector size is 13
hello3 vector size is 14
hello1 vector size is 15
hello3 vector size is 16
hello3 vector size is 17
hello3 vector size is 18

----------------------这样无论执行多少次既不会线程抢占,也不会数据丢失

4)使用synchronizedXxx封装后集合线程安全案例(效果和Vector类似)

public class SynchronizedListRight implements Runnable {  
    String name;  
    List<String> list;
  
    SynchronizedListRight(String name, List<String> list) {  
        this.name = name;  
        this.list = list;  
    }  
  
    public void run() {  
        System.out.println(name + "start");  
        
        for(int i = 0; i<6; i++){
        	synchronized(list){
        		list.add(name + ".add");  
        		System.out.println(name + " list size is " + list.size());  
        	}
            try {  
                Thread.sleep(10);  
            } catch(InterruptedException e) {  
                System.out.println(e.getMessage());  
            }  
        }  
    }  
  
    public static void main(String args[]) throws InterruptedException {  
  
    	List<String> list = Collections.synchronizedList(new ArrayList<String>());
  
        SynchronizedListRight hello1 = new SynchronizedListRight("hello1", list);  
        SynchronizedListRight hello2 = new SynchronizedListRight("hello2", list);  
        SynchronizedListRight hello3 = new SynchronizedListRight("hello3", list);  

        Thread h1 = new Thread(hello1);  
        Thread h2 = new Thread(hello2);  
        Thread h3 = new Thread(hello3);  
        h1.start();  
        h2.start();  
        h3.start();  
    }  
}  

执行结果:

hello3start
hello1start
hello3 list size is 1
hello2start
hello1 list size is 2
hello2 list size is 3
hello1 list size is 4
hello3 list size is 5
hello2 list size is 6
hello1 list size is 7
hello3 list size is 8
hello2 list size is 9
hello2 list size is 10
hello3 list size is 11
hello1 list size is 12
hello2 list size is 13
hello3 list size is 14
hello1 list size is 15
hello1 list size is 16
hello2 list size is 17
hello3 list size is 18

----------效果和第三种案例一样

© 著作权归作者所有

Joker上上签
粉丝 0
博文 8
码字总数 4630
作品 0
南昌
高级程序员
私信 提问
[Java 并发编程] 集合框架之 同步容器类 & 并发容器类

吾生也有涯,而知也无涯。———《庄子》 通过上一篇文章,我们已经知道设计一个线程安全类的原则和步骤,以及在设计过程中我们应当注意的细节。实际上,Java 的集合库包含了线程安全集合和非...

seaicelin
2018/05/25
0
0
再谈Java数据结构—分析底层实现与应用注意事项

在回顾js数据结构,写《再谈js对象数据结构底层实现原理-object array map set》系列的时候,在来整理下java的数据结构。 java把内存分两种:一种是栈内存,另一种是堆内存 基本类型在栈区分...

zhoulujun
05/17
50
0
HashMap和Hashtable的区别

HashMap和Hashtable的比较是Java面试中的常见问题,用来考验程序员是否能够正确使用集合类以及是否可以随机应变使用多种思路解决问题。HashMap的工作原理、ArrayList与Vector的比较以及这个问...

LCZ777
2014/03/29
95
0
Java线程面试题 Top 50

不管你是新程序员还是老手,你一定在面试中遇到过有关线程的问题。Java语言一个重要的特点就是内置了对并发的支持,让Java大受企业和程序员的欢迎。大多数待遇丰厚的Java开发职位都要求开发者...

loda0128
2015/05/29
966
1
08《Java核心技术》之Vector、ArrayList、LinkedList有何区别?

一、提出问题 我们在日常的工作中,能够高效地管理和操作数据是非常重要的。由于每个编程语言支持的数据结构不尽相同,比如我们最早接触到的 C 语言,需要自己实现很多基础数据结构,管理和操...

飞鱼说编程
2018/10/11
33
0

没有更多内容

加载失败,请刷新页面

加载更多

ES6

ES6:不改变原理的基础上,让API变得更简单 一、let:代替var用于声明变量 1、var的缺点: (1)声明提前 (2)没有块级作用域 2、let的优点: (1)组织了申明提前 (2)让let所在的块({}),...

wytao1995
今天
3
0
kubernetes 环境搭建 —— minikube

创建集群 minikube start 搭建好 k8s 集群后,可以查看集群的状态以及部署应用。主要用到的是 k8s 的 api,这通常需借助于 kutectl 命令行工具 基本操作 kubectl versionkubectl cluster-i...

lemos
今天
9
0
关于js混淆与反混淆还原操作

使用js的混淆加密,其目的是为了保护我们的前端代码逻辑,对应一些搞技术吃饭的公司来说,为了防止被竞争对手抓取或使用自己的代码,就会考虑如何加密,或者混淆js来达到代码保护。 1、为什么...

开源oschina
今天
11
0
用盛金公式解三次方程(ansi c版)

/* cc cubic.c -lm gcc cubic.c -lm Shengjin's Formulas Univariate cubic equation aX ^ 3 + bX ^ 2 + cX + d = 0, (a, b, c, d < R, and a!= 0). Multiple root disc......

wangxuwei
今天
9
0
JBolt开发平台入门(16)- 弹出Dialog显示指定区域的html内容

在JBolt里,有个主从表Demo。 子表中除了普通的table显示,还有其它从表显示形式 比如下方案例:是针对一个升级管理子表中存放版本的changelog富文本信息。 需求是点击左上角的弹出查看按钮,...

山东-小木
今天
46
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部