美好的一天!无法同步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