Добрый день!
Я столкнулся с проблемой синхронизации потоков. Я пишу программу, которая похожа на ужин философов. У меня есть несколько процессов (3, например) и ресурсов (4, например). Каждый процесс может работать только с 2 бесплатными ресурсами. Это означает, что 1-й процесс может работать только с 1-м и 2-м ресурсами и т. Д.
Я решил использовать семафоры для моей цели. Проблема в том, что до сих пор нет синхронизации. Например, если 1-й и 3-й процессы работают с ресурсами, то 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 начал работать, а он не может этого сделать !!