2017-08-10 87 views
0

假設我們有一個JobItem,它有兩個字段jobIddbTableName。 我們還有一個執行程序線程池4.帶有跳過項目的Java優先級隊列首先再處理

最初,執行程序將運行隊列中的第一個作業項目。 如果後面的隊列頭有相同的dbTableName說tableA,我想獲得下一個隊列項下一個沒有相同dbTableName的作業項並首先執行它。

隨着第一份工作可能需要很長的時間,我們最終可能已經處理與其他表的多個其他的工作項目,我們再次

處理TABLEA我們要確保對TableA的所有作業是按順序處理之前。

我有另一個列表,它保持當前正在運行的作業列表。

目前,我看到只有通過迭代隊列項目並檢查當前正在運行的作業列表才能提供此類功能。

有沒有更好的方法來實現這一目標?

謝謝

+0

你可以使用一個FIFO結構,並在您的隊列推回作業時,作業已經運行在桌子上使用相同的名稱 – Nathan

回答

0

對於每個表,你需要的就業機會單獨的輸入隊列串行執行。執行程序從隊列中獲取作業並按順序運行它們。串行執行程序可以通過兩種方式實現:作爲線程或作爲參與者。線程實現更簡單,但需要更多內存。 Actor實現需要額外的依賴線程庫。在你的情況下,演員圖書館可以簡化爲https://github.com/rfqu/CodeSamples/blob/master/src/simpleactor/SimpleActor.java

+0

感謝其的想法單獨的輸入作業隊列。使用這種方法將會更容易實現。 – Lucas

0

你可以創建具有隊列的線程池和工作線程。

public void execute(Runnable command) { 

     final int key= command.getKey(); 
     //Some code to check if it is runing 
     final int index = key != Integer.MIN_VALUE ? Math.abs(key) % size : 0; 
     workers[index].execute(command); 
    } 

工人代碼

private final AtomicBoolean scheduled = new AtomicBoolean(false); 

    private final BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<Runnable>(maximumQueueSize); 

    public void execute(Runnable command) { 
     long timeout = 0; 
     TimeUnit timeUnit = TimeUnit.SECONDS; 
     if (command instanceof TimeoutRunnable) { 
      TimeoutRunnable timeoutRunnable = ((TimeoutRunnable) command); 
      timeout = timeoutRunnable.getTimeout(); 
      timeUnit = timeoutRunnable.getTimeUnit(); 
     } 

     boolean offered; 
     try { 
      if (timeout == 0) { 
       offered = workQueue.offer(command); 
      } else { 
       offered = workQueue.offer(command, timeout, timeUnit); 
      } 
     } catch (InterruptedException e) { 
      throw new RejectedExecutionException("Thread is interrupted while offering work"); 
     } 

     if (!offered) { 
      throw new RejectedExecutionException("Worker queue is full!"); 
     } 

     schedule(); 
    } 

    private void schedule() { 
     //if it is already scheduled, we don't need to schedule it again. 
     if (scheduled.get()) { 
      return; 
     } 

     if (!workQueue.isEmpty() && scheduled.compareAndSet(false, true)) { 
      try { 
       executor.execute(this); 
      } catch (RejectedExecutionException e) { 
       scheduled.set(false); 
       throw e; 
      } 
     } 
    } 

    public void run() { 
     try { 
      Runnable r; 
      do { 
       r = workQueue.poll(); 
       if (r != null) { 
        r.run(); 
       } 
      } 
      while (r != null); 
     } finally { 
      scheduled.set(false); 
      schedule(); 
     } 
    }