线程编程四:给每个要共享的对象都加锁

在java3以前java没有提供线程安全的集合对象,之后有了很多,如 ConcurrentLinkedQueue、ConcurrentHashMap

 

集合对象往往用于缓存对象,特别是在服务器中,很大程度的提升服务的效率,他一般都被设计为共享资源。多线程环境下,对象共享需要加上锁,以保证线程安全。

 

我们可以如下设计

<span style="font-size:18px;">public class resource {
	private String name;
	private int xx;
	public synchronized String getName() {
		return name;
	}
	public synchronized void  setName(String name) {
		this.name = name;
	}
	public synchronized int getXx() {
		return xx;
	}
	public synchronized void setXx(int xx) {
		this.xx = xx;
	}
}</span>

以上设计,用到了resource实例的锁,他能很好的解决name  ,xx存取同步的问题。

但是,在很多情况下,resource是不能这么设计的,synchronized关键字让设计变得非常的复杂,并且对name ,xx的访问都不能异步了,

大部分情况下,我们这样设计:如果对象要求被共享,我们则把对象放入同步的环境中。

<span style="font-size:18px;">import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class resource {
	private Lock lock_Name = new ReentrantLock();
	private Lock lock_xx = new ReentrantLock();
	private String name;
	private int xx;
	public String getName() {
		try {
			lock_Name.lock();
			return name;
		}finally{
			lock_Name.unlock();
		}
		
	}
	
	public void  setName(String name) {
		try {
			lock_Name.lock();
			this.name = name;
		}finally{
			lock_Name.unlock();
		}
	}
	public int getXx() {
		
		try {
			lock_xx.lock();
			return xx;
		}finally{
			lock_xx.unlock();
		}
	}
	public void setXx(int xx) {
		
		try {
			lock_xx.lock();
			this.xx = xx;
		}finally{
			lock_xx.unlock();
		}
	}
}</span>


name 、xx都是要被共享的资源,但是彼此有不同的同步环境。

 

这也让我们想到了锁粒度的问题,粒度越小这会让程序性能更好,并且尽量的避免资源的竞争,是提高性能、预防死锁的设计结构

前面锁的粒度很大,resource实例会锁住所有的资源。后面的例子中锁则是每个资源都有一独立的锁。后面的设计更加的合理些。

 

回到java的集合对象,集合中有很多资源,要被共享的资源通常是集合中的“列表(数组)”,所以集合通常只对其中的“列表”加锁,而不会对其他的属性加锁,就算需要共享其他属性,也要加其他的锁,而不是统一用集合对象的锁。

 

 

 

 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值