在Doug lea的那本的《Java并發(fā)編程—設計原則與模式》,英文名" Concurrent Programming in Java™: Design Principles and Patterns, Second Edition",書中提到可以用信號量Semaphore實現互斥鎖Mutex。雖然java中是通過synchronize關鍵字提供鎖,并用這個基礎設施實現信號量的。在有的系統(tǒng)中只有信號量這一原語,鎖是通過信號量實現的。代碼如下:
import java.util.concurrent.Semaphore;
public class Mutex ...{
private Semaphore s = new Semaphore(1);
public void acquire() throws InterruptedException ...{
s.acquire();
}
public void release()...{
s.release();
}
public boolean attempt(int ms) throws InterruptedException ...{
return s.tryAcquire(ms);
}
}
上面的代碼只能在java5中編譯通過,因為Semaphore是在java5中才提供的。我在讀上面的代碼時有疑問。因為如果錯誤的連續(xù)調用release兩次,然后兩個線程都調用acquire,豈不是這兩個線程都可以同時運行,從而違背了互斥鎖的定義?為了證明我的猜測,寫了如下的代碼:
public class TestMutex ...{
public static void main(String[] args) throws InterruptedException...{
Mutex mutex=new Mutex();
mutex.acquire();
mutex.release();
mutex.release();
new MyThread(mutex).start();
new MyThread(mutex).start();
}
}
class MyThread extends Thread...{
private Mutex mutex;
public MyThread(Mutex mutex) ...{
this.mutex=mutex;
}
public void run()...{
try ...{
mutex.acquire();
} catch (InterruptedException e1) ...{
throw new RuntimeException(e1);
}
for(int i=0;i<10;i++)...{
System.out.print(i);
if(i%3==0)...{
try ...{
Thread.sleep(100);
} catch (InterruptedException e) ...{
e.printStackTrace();
}
}
}
mutex.release();
}
}
該程序的輸出如下:
00123123456456789789
從而證實了我的猜測。
import java.util.concurrent.Semaphore;
public class Mutex ...{
private Semaphore s = new Semaphore(1);
public void acquire() throws InterruptedException ...{
s.acquire();
}
public void release()...{
s.release();
}
public boolean attempt(int ms) throws InterruptedException ...{
return s.tryAcquire(ms);
}
}
上面的代碼只能在java5中編譯通過,因為Semaphore是在java5中才提供的。我在讀上面的代碼時有疑問。因為如果錯誤的連續(xù)調用release兩次,然后兩個線程都調用acquire,豈不是這兩個線程都可以同時運行,從而違背了互斥鎖的定義?為了證明我的猜測,寫了如下的代碼:
public class TestMutex ...{
public static void main(String[] args) throws InterruptedException...{
Mutex mutex=new Mutex();
mutex.acquire();
mutex.release();
mutex.release();
new MyThread(mutex).start();
new MyThread(mutex).start();
}
}
class MyThread extends Thread...{
private Mutex mutex;
public MyThread(Mutex mutex) ...{
this.mutex=mutex;
}
public void run()...{
try ...{
mutex.acquire();
} catch (InterruptedException e1) ...{
throw new RuntimeException(e1);
}
for(int i=0;i<10;i++)...{
System.out.print(i);
if(i%3==0)...{
try ...{
Thread.sleep(100);
} catch (InterruptedException e) ...{
e.printStackTrace();
}
}
}
mutex.release();
}
}
該程序的輸出如下:
00123123456456789789
從而證實了我的猜測。