只有一个线程可以访问某段代码?

时间:2012-07-11 06:45:40

标签: java multithreading

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

答案 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();
  }
}

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