java同步容器类的问题,vector等
大家都知道java中的同步容器类是线程安全的,但是在某些情况下可能需要额外的客户端加锁来保护复合操作。容器上的常见的复合操作是:迭代(遍历完容器中的所有容器),跳转(根据指定顺序找到当前元素的下一个个元素)以及条件运算 。最常见的例如”若没有则添加“(检查map中是否存在key值,不存在再添加)。
在同步容器类中,这些复合操作在没有客户端加锁的情况下仍然是线程安全的,但当其他线程并发地修改容器时,他们可能出现意料之外的行为。
例如以下vector的getLast和setLast操作。虽然大家都知道vector是线程安全的,但是在VectorDemo中getLast不是线程安全的,因为list.size()和list,get()这两个对list的操作不能保证他们俩的原子性,list.size()的结果在执行list.get()时可能已经发生状态了(被其他线程对list的remove所破坏)。让其变成线程安全的办法就是注释里的内容,就是锁住list。
package com.zy.charter5; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Vector; public class VectorDemo { public static Object getLast(Vector list) { int lastIndex = list.size() - 1; return list.get(lastIndex); } // public static Object getLast(Vector list) { // synchronized (list) { // int lastIndex = list.size() - 1; // return list.get(lastIndex); // } // } public static void print(Vector list) { for (int i = 0; i < list.size(); i++) { System.out.println(list.get(i)); } } } class Student { private String name; Student(String name) { this.setName(name); } public String getName() { return name; } public void setName(String name) { this.name = name; } }
上述的加锁方式是会存在死锁现象的,这个留在之后的章节进行介绍。
上一篇:
IDEA上Java项目控制台中文乱码