【高并发系列】19、JDK并发容器 - 线程安全的HashMap、List

1、Map

为防止多线程环境中使用HashMap出现问题,需要保证线程安全,可以使用Collections工具类下得synchronizedMap()方法:

public static <K,V> Map<K,V> synchronizedMap(Map<K,V> m) {
   return new SynchronizedMap<>(m);
}

返回的SynchronizedMap是Collections的私有静态内部类,使用委托,将所有map相关的功能交由传入的HashMap实现,而它只负责保证线程安全(使用synchronized关键字对所有操作加mutex锁),以下是部分源码:

private static class SynchronizedMap<K,V>
    implements Map<K,V>, Serializable {
    private static final long serialVersionUID = 1978198479659022715L;

    private final Map<K,V> m;     // Backing Map
    final Object      mutex;        // Object on which to synchronize

    SynchronizedMap(Map<K,V> m) {
        this.m = Objects.requireNonNull(m);
        mutex = this;
    }

    SynchronizedMap(Map<K,V> m, Object mutex) {
        this.m = m;
        this.mutex = mutex;
    }

    public int size() {
        synchronized (mutex) {return m.size();}
    }
    public boolean isEmpty() {
        synchronized (mutex) {return m.isEmpty();}
    }

    ...
}

虽然可以满足线程安全要求,但性能因为mutex的锁原因不算太好;

如果并发级别不高,一般可以使用,但在高并发环境中,可以使用ConcurrentHashMap类;

2、List

ArrayList和Vector都使用数组作为内部实现,但Vector是线程安全的,而ArrayList不是;

LinkedList使用链表结构实现了List,但不是线程安全的;

可以使用Collections.synchronizedList()方法来包装List:

public static <T> List<T> synchronizedList(List<T> list) {
    return (list instanceof RandomAccess ?
            new SynchronizedRandomAccessList<>(list) :
            new SynchronizedList<>(list));
}

与上面讲到的线程安全的Map类似,区别在于ArrayList和Vector实现了RandomAccess,而LinkedList没有实现,底层还是一样的:

static class SynchronizedRandomAccessList<E> extends SynchronizedList<E> implements RandomAccess
static class SynchronizedList<E>
    extends SynchronizedCollection<E>
    implements List<E> {
    private static final long serialVersionUID = -7754090372962971524L;

    final List<E> list;

    SynchronizedList(List<E> list) {
        super(list);
        this.list = list;
    }
    SynchronizedList(List<E> list, Object mutex) {
        super(list, mutex);
        this.list = list;
    }

    public boolean equals(Object o) {
        if (this == o)
            return true;
        synchronized (mutex) {return list.equals(o);}
    }
    public int hashCode() {
        synchronized (mutex) {return list.hashCode();}
    }

    ...
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值