Java concurrent包

来源:互联网 发布:eclipse打包java程序 编辑:程序博客网 时间:2024/05/16 14:33

概念

http://www.blogjava.net/xylz/archive/2010/07/08/325587.html

并发编程经常碰到的3个问题:原子性问题,可见性问题,有序性问题

这里写图片描述

主要从4个方面了解JUC:原子操作(atomic包)、锁(locks包)、容器(collections)和线程池(executor)

1. 原子操作

可参阅:http://ifeve.com/java-atomic/
JDK1.5的原子包:java.util.concurrent.atomic

java.util.concurrent是基于Queue的并发包,而Queue,很多情况下使用到了Atomic操作。

原子操作: 多个线程执行一个操作时,其中任何一个线程要么完全执行完此操作,要么没有执行此操作的任何步骤,那么这个操作就是原子的。

Atomic类的作用:原子化单一数据的操作;使用Atomic类构建复杂的,无需阻塞的代码;

原子包提供了一组原理类,主要分为4类(共12个类):
这里写图片描述

  1. AtomicBoolean,AtomicInteger,AtomicLong,AtomicReference
  2. AtomicIntegerArray,AtomicLongArray,AtomicReferenceArray
  3. AtomicIntegerFieldUpdater,AtomicLongFieldUpdater,AtomicReferenceFieldUpdater
  4. AtomicMarkableReference,AtomicStampedReference
  1. 基本类型:通过原子的方式更新基本类型。
  2. 数组类:通过原子的方式更新数组里的某个元素。
  3. 字段类:通过原子的方式更新某个类里的某个字段。原子更新字段类都是抽象类,每次使用都时候必须使用静态方法newUpdater创建一个更新器,原子更新类的字段的必须使用public volatile修饰符
  4. 引用类:原子更新基本类型的AtomicInteger,只能更新一个变量,如果要原子的更新多个变量,就需要使用这个原子更新引用类型提供的类

2. 锁机制

参阅:Java并发编程:Lock
JDK1.5的locks包:java.util.concurrent.locks提供如下有关接口和类:

  1. Lock
  2. ReentrantLock
  3. ReadWriteLock
  4. ReentrantReadWriteLock

synchronized缺陷

如果多个线程都只是进行读操作,所以当一个线程在进行读操作时,其他线程只能等待无法进行读操作。

一个代码块被synchronized修饰了,当一个线程获取了对应的锁,并执行该代码块时,其他线程便只能一直等待,等待获取锁的线程释放锁,而这里获取锁的线程释放锁只会有两种情况:
1. 获取锁的线程执行完了该代码块,然后线程释放对锁的占有
2. 线程执行发生异常,此时JVM会让线程自动释放锁

synchronized与Lock的区别

Lock提供了比synchronized更多的功能

  1. Lock不是Java语言内置的,synchronized是Java语言的关键字,因此是内置特性。Lock是一个接口(类),通过这个类可以实现同步访问;
  2. 采用synchronized不需要用户去手动释放锁,当synchronized方法或者synchronized代码块执行完之后,系统会自动让线程释放对锁的占用;而Lock则必须要用户去手动释放锁,如果没有主动释放锁,就有可能导致出现死锁现象。(通过Lock可以知道线程有没有成功获取到锁,而synchronized无法做到)

接口分析

1. Lock接口

public interface Lock {    void lock();    void lockInterruptibly() throws InterruptedException;    boolean tryLock();    boolean tryLock(long time, TimeUnit unit) throws InterruptedException;    void unlock();    Condition newCondition();}

将释放锁的操作放在finally块中进行,以保证锁一定被被释放,防止死锁的发生。形式:

Lock lock=...;lock.lock();try{    //处理任务}catch(Exception e){   //}finally{   lock.unlock();  //释放锁}

2. ReentrantLock

可重入锁:是唯一实现了Lock接口的类。可重入锁,也叫做递归锁,指的是同一线程 外层函数获得锁之后 ,内层递归函数仍然有获取该锁的代码,但不受影响。

2. ReadWriteLock

3. 并发容器

4. 线程池

0 0