java并发编程(三)客户端加锁与组合

本文深入探讨Java并发编程,重点关注客户端加锁的策略,通过实例分析了ArrayIndexOutOfBoundsException和ConcurrentModificationException的问题。同时,介绍了并发容器如ConcurrentHashMap、CopyOnWriteArrayList以及不同类型的BlockingQueue,如LinkedBlockingQueue、ArrayBlockingQueue和PriorityBlockingQueue在并发场景下的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

接上一篇《java并发编程(二)对象的共享

客户端加锁:

java为线程安全提供了一套安全的集合类操作 在java.util.Collections中,在多线程下能 安全的CRUD,但是应该注意,仅是对几何类进行同步,下面看一个实例。

若没有则添加实例:
public class ListHelper<E> {

	public List<E> list = Collections.synchronizedList(new ArrayList<E>());

	public synchronized boolean putIfAbsent(E x) {

		boolean absent = !list.contains(x);	//①
		if (absent)
			list.add(x);
		return absent;

	}

	public static void main(String[] args) {
		ListHelper<String> helper = new ListHelper<String>();

		new Thread(new Runnable() {

			@Override
			public void run() {
				helper.list.add("a");	//②
			}
		}).start();

		helper.putIfAbsent("a");

	}

}
我们在 处下断点调试后发现断点1处拿到的锁 是ListHelper 而断点2的锁是 由java虚拟机维护的,不是同一个锁,导致添加和判断不能同步,而在java 的API中也给出例子,要锁list例子
Returns a synchronized (thread-safe) list backed by the specified list. In order to guarantee serial access, it is critical that all access to the backing list is accomplished through the returned list.


It is imperative that the user manually synchronize on the returned list when iterating over it:


  List list = Collections.synchronizedList(new ArrayList());
      ...
  synchronized (list) {
      Iterator i = list.iterator(); // Must be in synchronized block
      while (i.hasNext())
          foo(i.next());
  }

一定要明确要保证谁是锁,不然加锁知识看似线程安全。

组合:

当为现在的类添加一个原子操作时,有一个种更好的方法:组合。我们不关心源是不是线程安全的,通过继承活着实现,给类添加同步实现线程安全(最好时实现借口,继承需要重写所有方法,并加同步)
public class ArrayListHelper<E> extends ArrayList<E>{
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值