【问题标题】:How to execute activate and deactivate methods of OSGI bundle in a single thread如何在单个线程中执行 OSGI 包的激活和停用方法
【发布时间】:2020-05-29 07:54:26
【问题描述】:

我有一个如下结构的 OSGI 包:

//...

public ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();

//...

@Activate
public void activate() {
   executor.submit(new Runnable() {
     @Override
     public void run() {
      //call 3 functions and log the data
     }
   }
}

@Deactivate
public void deactivate(){
  //call 2 other functions
}

activate 方法中的执行器确保在与所有其他捆绑线程分开的情况下调用 3 个函数,因为这些函数实际上实现了一些复杂的 Windows 消息循环,即 while true 循环,这就是为什么,为了不要阻止其他捆绑包,它会在单独的线程中激活。现在我很遗憾地注意到,为了在 deactivate 方法中运行 2 个函数,我需要在同一个线程中运行它们,其中运行了 activate 方法中的 3 个函数。简单地说,我需要确保我的 bundle 的激活和停用方法在同一个线程中运行,但仍要保持此 bundle 激活(在自己的线程中)与其他 bundle 分开。

我的问题是:如何实现这个?

我不是 Java 并发方面的专家,我也尝试过简单地在 deactivate 方法中调用此执行程序,但我不知道如何使用一个 Runnable 任务来执行此操作,因为在 deactivate 中我只需要调用2 个函数,并且仅激活 3 个函数,不应进行其他调用。

UPD:抱歉,我忘了说,在另一个包中有一个例程,它在某些情况下调用context.getBundle(0).stop() 以调用所有包的停用。如果我只想在 deactivate 方法中添加与 activate 相同的提交例程,那么在这种情况下我可以清楚地看到,提交正文中我的 bundle 的 deactivate 方法中的这两个函数没有被调用。

【问题讨论】:

    标签: java concurrency osgi


    【解决方案1】:

    只需在 deactivate 中执行另一个 executor.submit。由于它是一个单线程执行器,它将确保只有一个线程同时处理两者。

    唯一的问题是如何可靠地关闭执行器。通常在停用组件后应该关闭其所有资源。

    【讨论】:

    • 感谢您的评论。实际上,那是我最初的尝试。问题是,另一个包中有一个例程,它调用context.getBundle(0).stop() 以调用所有包的停用。在这种情况下,我在 Eclipse 中收到警告:Deactivating gp.osgi.executor.internal.PoolingExecutor,我可以清楚地看到,submit 主体中我的包的 deactivate 方法中的这两个函数没有被调用。抱歉,我应该在 OP-post 中提及它
    • 在你的 deactivate 中,在提交 runnable 以运行这 2 个方法后,调用 executor.awaitTermination(...) 并使用适当的超时时间等待 runnable 完成,然后再从 deactivate 方法返回。
    • 是的..有道理。
    【解决方案2】:

    这听起来是一个很常见的问题。我只想明确说明您正在使用线程并使用 Thread 中为此设计的方法。在激活时启动线程,在停用时中断它。您的主循环监视中断状态并在中断后执行您的停用功能。中断后,最好加入线程,以确保您的activate() 方法在后台线程完成运行您的停用函数之前不会返回。

    由于退出框架(停止捆绑 0)必须停止所有捆绑,并且停止的捆绑将停用其组件,这应该都可以工作。

     public class Foo extends Thread {
    
          @Activate   void activate()   { start(); }
          @Deactivate void deactivate() throws Exception { interrupt(); join(); }
    
          public void run() {
    
                while(!isInterrupted()) try {
                  ... your 3 function loop
                } catch( InterruptedException e) {
                  break;
                }
                ... 2 deactivate functions
          }
      }
    

    【讨论】:

      猜你喜欢
      • 2023-03-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-19
      相关资源
      最近更新 更多