下载安卓APP箭头
箭头给我发消息

客服QQ:3315713922

Java设计中如何使用Metux

作者:课课家教育     来源: http://www.kokojia.com点击数:826发布时间: 2016-02-29 16:28:21

标签: java编程java开发java继承

大神带你学编程,欢迎选课

  java中Mutex是互斥体,广泛地应用在多线程编程中。本文以广为流程的Doug Lea的concurrent工具包的Mutex实现为例,进行一点探讨。在Doug Lea的concurrent工具包中,Mutex实现了Sync接口,该接口是concurrent工具包中所有锁(lock)、门(gate)和条件变量(condition)的公共接口,Sync的实现类主要有:Mutex、aphore及其子类、Latch、CountDown、ReentrantLock等。这也体现了面向抽象编程的思想,使我们可以在不改变代码或者改变少量代码的情况下,选择使用Sync的不同实现。下面是Sync接口的定义:

Java设计中如何使用Metux_java编程_java开发_课课家

  public interface Sync

  public void acquire() throws InterruptedException;

  //获取许可

  public boolean attempt(long msecs) throws InterruptedException;

  //尝试获取许可

  public void release();

  //释放许可

  通过使用Sync可以替代java synchronized关键字,并提供更加灵活的同步控制。当然,并不是说 concurrent工具包是和Java synchronized独立的技术,其实concurrent工具包也是在synchronized的基础上搭建的,从下面对Mutex源码的解析即可以看到这一点。synchronized关键字仅在方法内或者代码块内有效,而使用Sync却可以跨越方法甚至通过在对象之间传递,跨越对象进行同步。这是Sync及concurrent工具包比直接使用synchronized更加强大的地方。

  注意Sync中的acquire()和attempt()都会抛出InterruptedException,所以使用Sync及其子类时,调用这些方法一定要捕获InterruptedException。而release()方法并不会抛出InterruptedException,这是因为在acquire()和attempt()方法中可能会调用wait()等待其它线程释放锁。而release()在实现上进行了简化,直接释放锁,不管是否真的持有。所以,你可以对一个并没有acquire()的线程调用release()这也不会有什么问题。而由于release()不会抛出InterruptedException,所以我们可以在catch或finally子句中调用release()以保证获得的锁能够被正确释放。比如:

  class X

  Sync gate; // ...

  public void m()

  try

  gate.acquire();

  // block until condition holds

  try

  // ... method body

  finally { gate.release(); }

  catch (InterruptedException ex) { // ... evasive action }

  Mutex是一个非重入的互斥锁。Mutex广泛地用在需要跨越方法的before/after类型的同步环境中。下面是Doug Lea的concurrent工具包中的Mutex的实现。

  public class Mutex implements Sync

  /** The lock status **/

  protected boolean inuse_ = false;

  public void acquire() throws InterruptedException

  if (Thread.interrupted()) throw new InterruptedException();//(1)

  synchronized(this)

  try

  while (inuse_) wait();

  inuse_ = true;

  catch (InterruptedException ex)

  //(2)

  notify();

  throw ex;

  public synchronized void release()

  inuse_ = false;

  notify();

  public boolean attempt(long msecs) throws InterruptedException

  if (Thread.interrupted()) throw new InterruptedException();

  synchronized(this)

  if (!inuse_)

  inuse_ = true;

  return true;

  else if (msecs <= 0)

  return false;

  else

  long waitTime = msecs;

  long start = System.currentTimeMillis();

  try

  for (;;)

  wait(waitTime);

  if (!inuse_)

  inuse_ = true;

  return true;

  else

  waitTime = msecs - (System.currentTimeMillis() - start);

  if (waitTime <= 0) // (3)

  return false;

  catch (InterruptedException ex)

  notify();

  throw ex;

赞(0)
踩(0)
分享到:
华为认证网络工程师 HCIE直播课视频教程