共享受限资源

共享受限资源

@(并发)[java, 并发, Thinking in Java]

1. 解决共享资源竞争

基本所有的并发模式在解决线程冲突问题的时候,都是采用序列化访问共享资源的方案,通常这是通过在代码前面加上一条语句实现的,这种机制称为互斥量

1.1. synchronized

共享资源一般是以对象形式存在的内存片段,然后把所有要访问这个资源的方法标记为synchronized。所有方法都自动含有单一的锁。当在对象上调用其任意synchronized方法时,此对象都被加锁,这是该对象上的其它synchronized方法只有等到前一个方法调用完毕并释放了锁之后才能被调用。

针对类,也有锁,所以synchronized static 方法可以在类的范围内防止对static数据的并发访问

每个访问临界资源的方法都必须同步

1.2. 显式的Lock对象

private Lock lock = new ReentrantLock();
public void next(){
    lock.lock();
    try{
    //
    }finally{
        lock.unlock();
    }
}

方法中紧接着对Lock的调用,必须放置在finally子句中带有unlock()的try-finally语句中

Lock()在加锁和释放锁方面,相对于内建的synchronized锁来说,赋予了更细粒度的控制力,如ReentrantLock允许尝试着获取但最终未获取锁,可以决定离开去执行其它事情,而不是等待直至这个锁被释放。

2. 原子性与易变性

原子操作是不能被线程调度机制中断的操作,原子性可以应用于除longdouble之外的所有基本类型之上的简单操作。
JVM可以将64位的的读取和写入当作两个分离的32位操作来执行,这有时称为字撕裂使用volatile就会获得原子性

volatile关键字确保了应用的可视性。如果将一个域声明为volatile的,那么只要对这个域产生了写操作,那么所哟的读操作都可以看到这个修改。因为volatile会立即被写入到主存中,而读操作就发生在主存中。

同步会导致向主存中刷新,因此如果一个域完全由synchronized方法或语句块防护,就不必将其设置为volatile的。

使用volatile的唯一安全的情况是类中只有一个可变的域,如果一个域可能会被多个任务同时访问,或者这些任务中至少有一个是写入任务,那么就应该将这个域设置为volatile的

3. 原子类

AtomicInteger, AtomicLong, AtomicReference等
boolean compareAndSet(expectedValue, undateValue): 原子性条件更新操作
这些类被调整为可以使用在某些现代处理器上的可获得的、并且在机器级别的原子性

4. 临界区

临界区:防止多个线程同时访问方法内部的部分代码

synchronized(syncObjct){
    //
}

称为同步控制块。在进入此段代码前必须得到syncObject对象的锁。

注意;synchronized关键字不属于方法特征签名的组成部分,所以可以在覆盖方法的时候加上。

5. 在其他对象上同步

在当前对象上同步:synchronized(this)
在其他对象上同步

private Object object = enw Object();
synchronized(object){
}

6. 线程本地存储

防止任务在共享资源上产生冲突的第二种方法:根除对变量的共享—-线程本地存储
java.lang.ThreadLocal
ThreadLocal类用于创建一个线程本地变量
在Thread中有一个成员变量ThreadLocals,该变量的类型是ThreadLocalMap,也就是一个Map,它的键是threadLocal,值为就是变量的副本。通过ThreadLocal的get()方法可以获取该线程变量的本地副本,在get方法之前要先set,否则就要重写initialValue()方法。ThreadLocal 不是用于解决共享变量的问题的,不是为了协调线程同步而存在,而是为了方便每个线程处理自己的状态而引入的一个机制.
ThreadLocal的使用场景:
数据库连接:在多线程中,如果使用懒汉式的单例模式创建Connection对象,由于该对象是共享的,那么必须要使用同步方法保证线程安全,这样当一个线程在连接数据库时,那么另外一个线程只能等待。这样就造成性能降低。如果改为哪里要连接数据库就来进行连接,那么就会频繁的对数据库进行连接,性能还是不高。这时使用ThreadLocal就可以既可以保证线程安全又可以让性能不会太低。但是ThreadLocal的缺点时占用了较多的空间。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值