java同步容器类的问题,vector等

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u013276277/article/details/81450210

    大家都知道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;
    }
} 

上述的加锁方式是会存在死锁现象的,这个留在之后的章节进行介绍。

猜你喜欢

转载自blog.csdn.net/u013276277/article/details/81450210