程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA編程入門知識 >> Java多線程同步設計中使用Metux

Java多線程同步設計中使用Metux

編輯:JAVA編程入門知識

  
  Mutex是互斥體,廣泛地應用在多線程編程中。本文以廣為流程的Doug Lea的concurrent工具包的Mutex實現為例,進行一點探討。在Doug Lea的concurrent工具包中,Mutex實現了Sync接口,該接口是concurrent工具包中所有鎖(lock)、門(gate)和條件變量(condition)的公共接口,Sync的實現類主要有:Mutex、Semaphore及其子類、Latch、CountDown、ReentrantLock等。這也體現了面向抽象編程的思想,使我們可以在不改變代碼或者改變少量代碼的情況下,選擇使用Sync的不同實現。下面是Sync接口的定義:
  
   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
  {
  
 
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved