美好的一天!無法同步Java中的線程(使用信號量)
我遇到了同步線程的問題。我正在寫程序,就像晚餐哲學家一樣。我有幾個進程(例如3個)和資源(例如4個)。每個進程只能使用2個免費資源。這意味着第一個進程只能使用第一個和第二個資源等。
我決定使用信號量來達到我的目的。問題是,仍然沒有同步。例如,如果第一個和第三個進程使用資源,則第二個進程必須等到他的資源不會被釋放。在我的程序中,有時會發生......有時它不會。
什麼問題?我該如何解決這個問題?
代碼是在這裏:
public class Sem
{
public Sem()
{
available = new ConcurrentHashMap< Integer, Semaphore >();//Resources.
for (int i = 1; i <= 4; i++)
{
available.put(i, new Semaphore(1, true));//Each resource contains semaphore.
}
}
public void start(final int id)
{
thisThread = new Thread()
{
public void run()
{
try
{
work(id); //Try to take resourses.
Thread.currentThread().sleep(1000);
release(id); //Release resources.
} catch (InterruptedException ex) {
Logger.getLogger(Sem.class.getName()).log(Level.SEVERE, null, ex);
}
}
};
thisThread.start();
}
public synchronized void work(int id) throws InterruptedException
{
available.get(id).acquire(); //Try to take resourse[id] and resourse[id+1]
available.get(id+1).acquire(); //Thread is blocking till it will be possible.
System.out.printf("Acquired [%s], id = %d\n",Thread.currentThread().getName(), id);
}
public void release(int id)
{
available.get(id).release(); //Release resources which hava been captured by thread.
available.get(id+1).release(); //After this other thread can take these resourses.
System.out.printf("Released [%s], id = %d\n",Thread.currentThread().getName(), id);
}
private ConcurrentHashMap< Integer, Semaphore > available; //Integer - id of thread[1..4]; Semaphore - is gate with param (1)
//Available - map of resources which can be busy by processes.
Thread thisThread;
}
我啓動該程序是這樣的:
Sem sem = new Sem();
sem.start(1);
sem.start(2);
sem.start(3);
我有幾個輸出消息,但我最喜歡的:
Acquired [Thread-1], id = 1
Acquired [Thread-3], id = 3
Released [Thread-1], id = 1
Acquired [Thread-2], id = 2
Released [Thread-3], id = 3
Released [Thread-2], id = 2
過程2開始工作,而他不能這樣做!
如果我嘗試同步發佈它顯示'Acquired [Thread-1],id = 1; 獲取[Thread-3],id = 3',然後什麼都不做... – ExR 2011-04-23 17:10:32
至少我認爲你是正確的線程... – ExR 2011-04-23 17:14:19
如果不是同步(this),你嘗試同步(acquireObject)和同步(releaseObject)。線程2只是進入同步塊,並在信號量上阻塞 - 經典死鎖,因爲其他線程無法進入釋放。 – 2011-04-23 17:16:31