`

jdk5 concurrent 初学

    博客分类:
  • java
阅读更多
由于上次发现了ReentrantLock,同步的另外一种实现,可提供更好的性能和吞吐率,这么一样好东西。
从包名来看又是java.util.concurrent ,看来这个concurrent 真的不简单啊。于是想学习学习
concurrent。concurrent的中文意思是并行,估计就是sun特别为了并发情况、多线程做的增强和修补。对哪些东西增强了呢?
先看看java.util.concurrent以及子包中的东西
1)java.util.concurrent,concurrent 首先增强的是Collection;
2)java.util.concurrent.locks,ReentrantLock实际是在它里面,locks顾名思义, 提供的就是锁。
3)java.util.concurrent.atomic,这个比较有意思, 里面都是对Integer、Long,以及它们的数组的一个原子化操作的封装类, 什么是原子操作?实际上就是最小的单元操作, 该操作是线程安全的,保证了数据的原子性和可见性。

主要关注一下1)看看
java.util.concurrent为Collection带了些什么,这里是接口列表http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/package-tree.html
看到interface列表,主要就是BlockingQueue,Executor,ConcurrentMap
a)ConcurrentMap,A Map providing additional atomic putIfAbsent, remove, and replace methods. 看来也是提供了对Map的原子操作,同样是加强了线程安全。
b)BlockingQueue,
引用

BlockingQueue implementations are thread-safe. All queuing methods achieve their effects atomically using internal locks or other forms of concurrency control. However, the bulk Collection operations addAll, containsAll, retainAll and removeAll are not necessarily performed atomically unless specified otherwise in an implementation. So it is possible, for example, for addAll(c) to fail (throwing an exception) after adding only some of the elements in c.
#BlockingQueue 的实现都是线程安全的,里面的方法保障了并发情况下的原子操作,但bulk Collection operations是例外,因为没有必要用原子操作。

A BlockingQueue does not intrinsically support any kind of "close" or "shutdown" operation to indicate that no more items will be added. The needs and usage of such features tend to be implementation-dependent. For example, a common tactic is for producers to insert special end-of-stream or poison objects, that are interpreted accordingly when taken by consumers.
#BlockingQueue本质上并没有提供close和shutdown操作,即使当队列已经满无法添加新元素。

Usage example, based on a typical producer-consumer scenario. Note that a BlockingQueue can safely be used with multiple producers and multiple consumers.
#以下是一个示例,表明BlockingQueue 可以在多线程环境下安全的表现生产-消费模型。
 class Producer implements Runnable {
   private final BlockingQueue queue;
   Producer(BlockingQueue q) { queue = q; }
   public void run() {
     try {
       while(true) { queue.put(produce()); }
     } catch (InterruptedException ex) { ... handle ...}
   }
   Object produce() { ... }
 }

 class Consumer implements Runnable {
   private final BlockingQueue queue;
   Consumer(BlockingQueue q) { queue = q; }
   public void run() {
     try {
       while(true) { consume(queue.take()); }
     } catch (InterruptedException ex) { ... handle ...}
   }
   void consume(Object x) { ... }
 }

 class Setup {
   void main() {
     BlockingQueue q = new SomeQueueImplementation();
     Producer p = new Producer(q);
     Consumer c1 = new Consumer(q);
     Consumer c2 = new Consumer(q);
     new Thread(p).start();
     new Thread(c1).start();
     new Thread(c2).start();
   }
 }




c)Executor
引用
An object that executes submitted Runnable tasks. This interface provides a way of decoupling task submission from the mechanics of how each task will be run, including details of thread use, scheduling, etc.

看出来了,Executor实际上是对线程Runnable 的封装,提供了更多功能。
查看Executor的继承接口ExecutorService可以了解到多了哪些功能:
引用
An ExecutorService can be shut down, which will cause it to stop accepting new tasks. After being shut down, the executor will eventually terminate, at which point no tasks are actively executing, no tasks are awaiting execution, and no new tasks can be submitted.
Method submit extends base method Executor.execute(java.lang.Runnable) by creating and returning a Future that can be used to cancel execution and/or wait for completion. Methods invokeAny and invokeAll perform the most commonly useful forms of bulk execution, executing a collection of tasks and then waiting for at least one, or all, to complete. (Class ExecutorCompletionService can be used to write customized variants of these methods.)

从方法来看,主要有shutdown、invokeAll、invokeAny、submit,
另外还需要特别注意一下Future和Callable,Future表示线程运行状况和结果,Callable是类似Runable的另外一种线程接口, 却在运行时可以带返回值,这个返回值就是Future:
引用

Callable:
A task that returns a result and may throw an exception. Implementors define a single method with no arguments called call.

The Callable interface is similar to Runnable, in that both are designed for classes whose instances are potentially executed by another thread. A Runnable, however, does not return a result and cannot throw a checked exception.

Future:
A Future represents the result of an asynchronous computation. Methods are provided to check if the computation is complete, to wait for its completion, and to retrieve the result of the computation. The result can only be retrieved using method get when the computation has completed, blocking if necessary until it is ready. Cancellation is performed by the cancel method. Additional methods are provided to determine if the task completed normally or was cancelled. Once a computation has completed, the computation cannot be cancelled. If you would like to use a Future for the sake of cancellability but not provide a usable result, you can declare types of the form Future<?> and return null as a result of the underlying task.


比较实用的还是ScheduledExecutorService,跟以前的Timer类似,也是用作线程的定时任务,特别的是通过Executors.newScheduledThreadPool可以将ScheduledExecutorService用线程池缓存起来。
import static java.util.concurrent.TimeUnit.*;
 class BeeperControl {
    private final ScheduledExecutorService scheduler = 
       Executors.newScheduledThreadPool(1);

    public void beepForAnHour() {
        final Runnable beeper = new Runnable() {
                public void run() { System.out.println("beep"); }
            };
        final ScheduledFuture<?> beeperHandle = 
            scheduler.scheduleAtFixedRate(beeper, 10, 10, SECONDS);
        scheduler.schedule(new Runnable() {
                public void run() { beeperHandle.cancel(true); }
            }, 60 * 60, SECONDS);
    }
 }






  • 描述: concurrent
  • 大小: 224.1 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics