重新安排创建的线程并在固定延迟后停止它

时间:2017-07-27 06:56:37

标签: java spring multithreading

我面临一个关于重新安排现有线程的问题。基本上我想在函数调用中创建一个带有一些标识符的新线程,并在一段指定的时间后停止它让我们说5分钟。现在将发生两个案例

  1. 如果同一个函数在5分钟内再次使用相同的标识符进行调用,那么线程必须从当前时间再重新安排其停止时间5分钟。

  2. 如果相同的功能在5分钟后再次使用相同的标识符进行调用,那么新的线程将创建将在5分钟后停止。

  3. 我该如何实现?

2 个答案:

答案 0 :(得分:0)

这接近于过于宽泛,但这是一个简单的方法,如何解决这些问题:

  • 您为时间戳创建了一个持有者,可以以线程安全的方式读取和写入
  • 当新线程启动时,它只是将当前时间写入该持有者
  • 当线程仍在运行时调用该函数时,"其他"代码只是将时间戳更新为当前时间
  • 该线程应定期检查时间戳 - 当线程找到" now> = timestamp + 5 min)时 - 您知道5分钟结束且线程可以停止。

答案 1 :(得分:0)

我得到了答案。我所做的基本上是创建了一个地图,可以将字符串存储为键,将ScheduledFuture对象存储为值。我使用executor.schedule()方法创建延迟为5分钟的线程。在更新方法中,将在map中检查线程是否存在。如果在那种情况下不可用,方法将创建具有5分钟延迟的新线程并将其添加到betamap对象。如果在5分钟内使用相同线程名称调用更新方法,则通过调用t.cancel(false)取消线程,并创建一个延迟5分钟的新线程并将其存储在betamap中。 5分钟后,将调用run方法,并且线程将自动停止。但是在run方法中,我需要从map中删除当前正在执行的线程。 我不知道你解释的方式是否被你们理解,但我会在下面放置代码,这可能有助于理解。

代码我做了什么

公共类BetaUserServiceImpl {

    public static ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(15); 

        static ScheduledFuture<?> t,t1;

        public static ConcurrentHashMap<String, ScheduledFuture<?>> betaMap = new ConcurrentHashMap<>();

        int timeDelay = 5;

        public void update(String threadname)
        {

        synchronized (betaMap) {

        if (betaMap.containsKey(threadname))
            {

        t = betaMap.get(threadname);

        t.cancel(false);

        Iterator it = betaMap.entrySet().iterator();

            while (it.hasNext())
             {

               Entry item = (Entry) it.next();

                if(item.getKey().equals(threadname))
                {
                   betaMap.remove(item.getKey());   
               }
            }
            t1=executor.schedule(new BetaUserThreadSchedular("thread1"), 
            timeDelay,TimeUnit.SECONDS);

            betaMap.put(threadname, t1);
        }
        else
         {
        t=executor.schedule(new BetaUserThreadSchedular(threadname),timeDelay,TimeUnit.SECONDS);
        betaMap.put(threadname, t);
        }
        }
        }

}

线程类

公共类BetaUserThreadSchedular实现了Runnable {

private Thread thread;
private String deviceId;

 public BetaUserThreadSchedular(String deviceId) {
        this.deviceId = deviceId;
    }

public void run() {

    synchronized (BetaUserServiceImpl.betaMap) {
        try {

             Iterator it = BetaUserServiceImpl.betaMap.entrySet().iterator();
                while (it.hasNext())
                {
                   Entry item = (Entry) it.next();
                   if(item.getKey().equals(deviceId)  )
                   {

                       BetaUserServiceImpl.betaMap.remove(item.getKey());   
                   }
                }

        }catch (Exception e) {
            logger.info(e);
        }   
    }
}

public void start() {
    thread = new Thread(this);
    thread.start();
}

}