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开始工作,而他却做不到!
Good day!
I have met problem with synchronizing threads. I am writing program which is like dinner philosophers. I have few processes (3 for example) and resources (4 for example). Each process can work only with 2 free resources. That means that 1st process can work only with 1st and 2nd resources and etc.
I decided to use semaphores for my aim. Problem is that is still doesn't have synchronization. For example if 1st and 3rd processes are working with resources then 2nd process must wait until his resources will not be release. In my program sometimes it happens... Sometimes it doesn't.
What is the problem? How can i solve that?
Code is here:
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;
}
I start this program like this:
Sem sem = new Sem();
sem.start(1);
sem.start(2);
sem.start(3);
I have few output messages but my favorite:
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
Process 2 started worked while he can't do it!!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我认为你应该以与获取锁相反的顺序释放锁。
I think you should release the locks in reverse order in which they were obtained.
根据您的代码和输出,线程 3 可能释放了信号量 3,因此等待它的线程 2 在线程 3 完成之前获取了信号量并打印了消息。
我注意到你没有同步释放方法。
我强烈建议在获取和释放周围放置同步块。
Based on your code and output, it is possible that Thread 3 released semaphore 3 so Thread 2 that was waiting for it - acquired it and printed the message before Thread 3 completed.
I noticed that you didn't synchronized release method.
I highly recommend putting synchronized block around both acquire and release.
您先完成资源,然后再完成线程,因此首先释放资源信号量。将释放方法替换为以下内容:
You are finishing with the resource first then the thread so release the resource semaphore first. Replace the release method with followings: