2

我有一个项目需要不时登录我的路由器并进行一些更改。在 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)
  {

  }
}

所以我所做的是使方法同步,但我相信不时有多个线程访问“rebo​​otRouter”方法。这会导致我的主要应用程序出现问题。

使 IpManager.rebootRouter() 仅由一个线程执行的最佳方法和最有效的方法是什么?

问候!

4

4 回答 4

1

synchronized保证一次只有一个线程可以进入块,但是同一个线程可以多次进入块(所以线程不会对自己死锁),如果一个线程因为另一个线程在那里而被阻塞,那么它可能在第一个线程离开同步块后立即运行。

首先,我会在例程的入口和出口点记录日志。我会检查您是否正在进行任何递归,并确保调用确实同时运行。另外,请记住,如果有任何异步工作或回调,同步块可能会退出。

于 2012-07-11T06:56:01.113 回答
1

使用Semaphore from java.util.concurrent package,限制访问对象的线程数。

例子:

在此代码片段中,一次只有 1 个线程可以访问该对象。

Semaphore s = new Semaphore(1);  

s.acquire();

synchronized(this){

// Your modem work

}

s.release();
于 2012-07-11T07:01:34.873 回答
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 可能导致问题的东西。

于 2012-07-11T07:08:58.630 回答
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();
  }
}

如果您的需求更具体,您可能需要重新表述您的问题。

于 2012-07-11T07:42:17.973 回答