JDK5.0关于多线程的新特性

概述
1:三个新加的多线程包
2:Callable 和 Future 接口
3:新的线程执行架构
4:Lockers 和Condition 接口
5: Synchronizer:同步装置
6: BlockingQueue 接口
7:Atomics 原子级变量
8:Concurrent Collections 共点聚集


1:三个新加的多线程包
  java.util.concurrent,
    包含了常用的多线程工具,是新的多线程工具的主体。

  java.util.concurrent.atomic,
    包含了不用加锁情况下就能改变值的原子变量
    比如说AtomicInteger 提供了addAndGet()方法

  java.util.concurrent.locks
    包含锁定的工具。

2:Callable 和 Future 接口
  Callable 和Runnable 有几点不同:
    Callable 规定的方法是call(),而Runnable 规定的方法是run().
    Callable 的任务执行后可返回值,而Runnable 的任务是不能返回值的。
    call()方法可抛出异常,而run()方法是不能抛出异常的。
  运行 Callable 任务可拿到一个Future 对象,通过Future 对象可了解任务
  执行情况,可取消任务的执行,还可获取任务执行的结果。

import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class Executor {
  public static void main(String[] args){
  //*1
  DoCallStuff call1 = new DoCallStuff(0);
  DoCallStuff call2 = new DoCallStuff(1);
  DoCallStuff call3 = new DoCallStuff(2);
  //*2
  ExecutorService es = Executors.newFixedThreadPool(3);
  //*3
  Future<String> future1 = es.submit(call1);
  Future<String> future2 = es.submit(call2);
  Future<String> future3 = es.submit(call3);
  try {
    //*4
    System.out.println(future1.get());
    //*5
    Thread.sleep(3000);
    System.out.println("Thread 2 terminated? :" + future2.cancel(true));
    //*6
    System.out.println(future3.get());
  } catch (ExecutionException ex) {
    ex.printStackTrace();
  }
}

 

3:新的线程执行架构
  主要由三个接口和其相应的具体类组成。
  这三个接口是Executor, ExecutorService 和ScheduledExecutorService,


4:Lockers 和Condition 接口
  Lockers接口
    在5.0 以前,锁定的功能是由Synchronized 关键字来实现的,这样做存在几个问题:
    每次只能对一个对象进行锁定。若需要锁定多个对象,编程就比较麻烦,
    一不小心就会出现死锁现象。
    如果线程因拿不到锁定而进入等待状况,是没有办法将其打断的
    Java 5.0 里出现两种锁的工具可供使用:Lock和ReadWriteLock

  Condition接口
    用于处理经典的生产者、消费者问题

5: Synchronizer:同步装置
  Java 5.0 里新加了4 个协调线程间进程的同步装置,
  它们分别是Semaphore, CountDownLatch, CyclicBarrier 和Exchanger

  Semaphore:
    用来管理一个资源池的工具,Semaphore 可以看成是个通行证,线程要想从资
    源池拿到资源必须先拿到通行证,Semaphore 提供的通行证数量和资源池的大
    小一致。如果线程暂时拿不到通行证,线程就会被阻断进入等待状态。

  CountDownLatch:
    CountDownLatch 是个计数器,它有一个初始数,等待这个计数器的线程必须等
    到计数器倒数到零时才可继续。比如说一个Server 启动时需要初始化4 个部件,
    Server 可以同时启动4 个线程去初始化这4 个部件,然后调用
    CountDownLatch(4).await()阻断进入等待,每个线程完成任务后会调用一次
    CountDownLatch.countDown()来倒计数, 当4 个线程都结束时
    CountDownLatch 的计数就会降低为0,此时Server 就会被唤醒继续下一步操作

  CyclicBarrier:
    CyclicBarrier 类似于CountDownLatch 也是个计数器,不同的是CyclicBarrier
    数的是调用了CyclicBarrier.await()进入等待的线程数,当线程数达到了
    CyclicBarrier 初始时规定的数目时,所有进入等待状态的线程被唤醒并继续。
    (似乎没有什么现实中的好例子)

  Exchanger:
    顾名思义 Exchanger 让两个线程可以互换信息。用一个例子来解释比较容易。
    例子中服务生线程往空的杯子里倒水,顾客线程从装满水的杯子里喝水,然后通
    过Exchanger 双方互换杯子,服务生接着往空杯子里倒水,顾客接着喝水,然
    后交换,如此周而复始。

6: BlockingQueue 接口
  BlockingQueue 是一种特殊的Queue,若BlockingQueue 是空的,从
  BlockingQueue 取东西的操作将会被阻断进入等待状态直到BlocingkQueue 进
  了新货才会被唤醒。同样,如果BlockingQueue 是满的任何试图往里存东西的
  操作也会被阻断进入等待状态,直到BlockingQueue 里有新的空间才会被唤醒
  继续操作

7:Atomics 原子级变量
  原子量级的变量,主要的类有 AtomicBoolean, AtomicInteger,
  AotmicIntegerArray, AtomicLong, AtomicLongArray, AtomicReference ……。
  这些原子量级的变量主要提供两个方法:
  compareAndSet(expectedValue, newValue):
    比较当前的值是否等于expectedValue,若等于把当前值改成newValue,并返回true。若不等,返回false。
  getAndSet(newValue):
    把当前值改为newValue,并返回改变前的值。
    这些原子级变量利用了现代处理器(CPU)的硬件支持可把两步操作合为一步的功能,避免了不必要的锁定,提高了程序的运行效率。


8:Concurrent Collections 共点聚集
  在 Java 的聚集框架里可以调用Collections.synchronizeCollection(aCollection)
  将普通聚集改变成同步聚集,使之可用于多线程的环境下。但同步聚集在一个
  时刻只允许一个线程访问它,其它想同时访问它的线程会被阻断,导致程序运行
  效率不高。Java 5.0 里提供了几个共点聚集类,它们把以前需要几步才能完成的
  操作合成一个原子量级的操作,这样就可让多个线程同时对聚集进行操作,避免
  了锁定,从而提高了程序的运行效率。Java 5.0 目前提供的共点聚集类有:
  ConcurrentHashMap, ConcurrentLinkedQueue, CopyOnWriteArrayList 和
  CopyOnWriteArraySet.

来源:
http://wenku.baidu.com/view/77aff7e96294dd88d0d26b7b.html

posted @ 2012-07-08 21:25  万法自然~  阅读(246)  评论(0)    收藏  举报