我有一个项目,需要不时登录我的路由器并进行一些更改。在eclipse中,我有一个单独的项目,处理我需要更改的所有内容,我在主项目的构建路径中有一个多线程项目。我的问题是,有时两个线程试图访问路由器,这会让事情变得混乱。有什么我可以做的,只有一个线程可以访问我的代码的一部分。
这是主要多线程应用程序的相关代码
if (totalLogins > 10)
{
IpManager.rebootRouter();
Thread.sleep(4000);
totalLogins = 0;
composedMessagesWithThisIP = 0;
}
在另一个项目中,这就是我所拥有的
public synchronized static void rebootRouter()
{
try
{
//code related to restart modem
}
catch (Exception e)
{
}
}
所以我所做的是使方法同步,但我不时相信不止一个线程访问“rebootRouter”方法。这导致我的主要应用程序出现问题。
使IpManager.rebootRouter()仅由一个线程执行的最佳方法和最有效的方法是什么?
问候!
答案 0 :(得分:2)
使用java.util.concurrent package
中的信号量,限制访问该对象的线程数。
示例:强>
在此代码段中,一次只有一个线程可以访问该对象。
Semaphore s = new Semaphore(1);
s.acquire();
synchronized(this){
// Your modem work
}
s.release();
答案 1 :(得分:1)
synchronized
保证一次只能有一个线程进入该块,但AFAIR同一个线程可以多次进入该块(因此线程不会自行死锁),如果一个线程被阻塞,另一个线程在那里然后它可能在第一个线程离开同步块后立即运行。
首先,我将日志记录在例程的入口和出口点。 我会检查你没有进行任何递归,并确保这些调用确实在同一时间运行。此外,请记住,如果有任何异步工作或回调,可以退出同步块。
答案 2 :(得分:0)
So what I have done is made the method synchronized but I believe from time to time more than one thread access the "rebootRouter" method.
由于您已将此方法标记为synchronized
,因此可确保多个线程无法同时执行此方法。侧面// Your modem work
中的代码可能包含一些可能导致问题的unsynchronized
内容。
答案 3 :(得分:0)
我的问题是,有时两个线程试图访问路由器,这会让事情变得混乱。有什么我可以做的,只有一个线程可以访问我的代码的一部分。
定义“搞砸事情”。由于rebootRouter
已同步,因此在任何给定时间只有一个线程可以运行该方法。但是如果一个线程,称之为线程A,尝试调用它,而另一个线程(线程B)运行它,线程A将阻塞直到B从rebootRouter
返回,然后A将直接调用rebootRouter
本身。如果这是您想要的行为,那么您的问题就在其他地方(synchronized
没有被破坏,或者有人会注意到。)
如果您希望上面示例中的线程A在上面的示例中被另一个线程调用时不调用rebootRouter
,则可以使用Lock.tryLock
:
private static final Lock lock = new ReentrantLock();
public static void rebootRouter() {
if (!lock.tryLock()) return;
try {
//code related to restart modem
} catch (Exception e) {
// Note: Empty catch blocks considered bad style
} finally {
lock.unlock();
}
}
如果您的需求更具体,您可能需要重新提出问题。