欢迎使用CSDN-markdown编辑器

来源:互联网 发布:兰州理工大学 软件学院 编辑:程序博客网 时间:2024/06/05 05:12

10.8J.U.C包详解

Jdk 1.5之后增加了动态并发库 设计三个包

java.util.concurrent
这个包提供了并发编程中的一些实用的工具

java.util.concurrent.atomic
这个包支持单个变量上接触锁的线程安全编程

java.util.concurrent.locks
这个包为锁和等待条件提供一个框架的接口和类 它不同于内置的同步监视器

10.8.1java.util.concurrent.atomic
支持在单个变量上解除锁的线程安全编程。

可以用原子方式更新的 int 值。有关原子变量属性的描述,

源码的实现:

getAndIncrement方法在一个死循环中for(;;) ,这里能得到当前的值 用临时变量next让当前的值加1;然后调用compareAndSet方法。然后调用unsafe.compareAndSwapInt这里其实就是不断尝试得到一个比当前值大1 的新值,然后将这个值赋给自己,如果失败进入下一次循环 一直设置到成功为止。

10.8.2java.util.concurrent.locks
为锁和等待条件提供一个框架的接口和类,它不同于内置同步和监视器。

10.8.2.1Lock锁
Lock接口有一个实现类ReentrantLock

使用这样的方式与synchronized的功能是完全一样的,这些代码开起来更加面向对象,怎样加锁怎样解锁 一目了然。
另外ReentrantLock和synchronized相比 增加了一些功能:
等待可中断
这是指当前持有锁的线程如果长期不释放锁,在等待的过程中可以放弃等待,处理其他事情。
公平锁
这个说多个线程在等待同一个锁,必须按照申请锁的时间依次获得锁。Synchronized中的锁是不公平锁,锁被释放的时候 任何一个等待锁的线程都有相同的机会获得锁。ReentrantLock默认也是不公平锁,但是可以使用构造函数使其改为公平锁
Lock lock = new ReentrantLock(true);
绑定条件
条件锁

从性能上说ReentrantLock比synchronized性能会好一些 但是在jdk1.6之后经过优化基本相同 但是还是推荐使用ReentrantLock

10.8.2.2Condition条件锁

10.8.2.3ReadWriteLock读写锁

ReadWriteLock 维护了一对相关的锁,一个用于只读操作,另一个用于写入操作。只要没有 writer,读取锁可以由多个 reader 线程同时保持。写入锁是独占的。

典型的缓存的应用

重入
此锁允许 reader 和 writer 按照 ReentrantLock 的样式重新获取读取锁或写入锁。在写入线程保持的所有写入锁都已经释放后,才允许重入 reader 使用它们。
此外,writer 可以获取读取锁,但反过来则不成立。在其他应用程序中,当在调用或回调那些在读取锁状态下执行读取操作的方法期间保持写入锁时,重入很有用。如果 reader 试图获取写入锁,那么将永远不会获得成功。
锁降级
重入还允许从写入锁降级为读取锁,其实现方式是:先获取写入锁,然后获取读取锁,最后释放写入锁。但是,从读取锁升级到写入锁是不可能的。
能从写入锁降级到读取锁 但是反过来不成立
10.8.3java.util.concurrent
这个包主要包含了以下内容

线程池
并发容器
同步工具

10.8.3.1线程池
线程池的概念: 线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务。线程池线程都是后台线程。每个线程都使用默认的堆栈大小,以默认的优先级运行,并处于多线程单元中。如果某个线程在托管代码中空闲(如正在等待某个事件),则线程池将插入另一个辅助线程来使所有处理器保持繁忙。如果所有线程池线程都始终保持繁忙,但队列中包含挂起的工作,则线程池将在一段时间后创建另一个辅助线程但线程的数目永远不会超过最大值。超过最大值的线程可以排队,但他们要等到其他线程完成后才启动。

在jdk1.5之后 可以使用java内置线程池 java.util.concurrent. 类创建线程池

案例一:

假如有10个任务 如果开启线程 我们可以开启10个线程完成这10个任务,如果使用线程池也也可同样完成任务

10.8.3.2容器
10.8.3.2.1同步容器
容器就是指集合 我们可以将对象通过集合相关的方法 丢在集合中在集合中 查找 移除
Hashtable和Vector是线程安全的
在某些特殊的情况下 需要对vector和hashtable进行处理

两个线程其中一个对集合进行迭代 另外一个线程对集合进行删除 导致集合抛出ConcurrentModificationException错误。虽然容器是保证安全的,但是这个异常是在遍历集合的时候 容器被修改锁抛出的异常
但是还需要对操作的过程加锁

这样的代码对容器迭代进行了加锁操作 当其他线程访问容器的时候 需要进入等待状态 一直等待上一个线程释放资源 。性能将会低下,将不能满足该高并发的需要环境。虽然是保证了线程的安全。性能比较低下。
10.8.3.2.2并发容器
JUC包下提供了以下几种并发容器 ,并发容器专门为多线程而设计的。

ConcurrentHashMap 是替代Map同步容器的并发容器的实现
CopyOnWriteArrayList是替代List同步容器的并发容器的实现
CopyOnWriteArraySet是替代Set同步容器的并发容器的实现
ConcurrentLinkedQueue是替代Queue同步容器的并发容器的实现

10.8.3.2.2.1ConcurrentHashMap

HashMap底层是维护了一个数组,每个数组又是一个单向链表 数组+链表

ConcurrentHashMap在结构上发生了一些变化,ConcurrentHashMap提高了并发能力,在内部维护了一个内部类Segment

原创粉丝点击