在Doug lea的那本的《Java并發(fā)編程—設(shè)計(jì)原則與模式》,英文名" Concurrent Programming in Java™: Design Principles and Patterns, Second Edition",書(shū)中提到可以用信號(hào)量Semaphore實(shí)現(xiàn)互斥鎖Mutex。雖然java中是通過(guò)synchronize關(guān)鍵字提供鎖,并用這個(gè)基礎(chǔ)設(shè)施實(shí)現(xiàn)信號(hào)量的。在有的系統(tǒng)中只有信號(hào)量這一原語(yǔ),鎖是通過(guò)信號(hào)量實(shí)現(xiàn)的。代碼如下:
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中編譯通過(guò),因?yàn)镾emaphore是在java5中才提供的。我在讀上面的代碼時(shí)有疑問(wèn)。因?yàn)槿绻e(cuò)誤的連續(xù)調(diào)用release兩次,然后兩個(gè)線程都調(diào)用acquire,豈不是這兩個(gè)線程都可以同時(shí)運(yùn)行,從而違背了互斥鎖的定義?為了證明我的猜測(cè),寫(xiě)了如下的代碼:
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
從而證實(shí)了我的猜測(cè)。
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中編譯通過(guò),因?yàn)镾emaphore是在java5中才提供的。我在讀上面的代碼時(shí)有疑問(wèn)。因?yàn)槿绻e(cuò)誤的連續(xù)調(diào)用release兩次,然后兩個(gè)線程都調(diào)用acquire,豈不是這兩個(gè)線程都可以同時(shí)運(yùn)行,從而違背了互斥鎖的定義?為了證明我的猜測(cè),寫(xiě)了如下的代碼:
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
從而證實(shí)了我的猜測(cè)。