2013-02-21 259 views
1

我有一个优先级队列,按日期顺序列出来自sql数据库的作业的aload。然后,我得到最接近的DelinelineJob函数,获取最高职位,检查是否有其他工作具有相同的日期,然后比较优先级,以查看哪些是最重要的工作。然后我回到最高职位。java优先级队列队列适应

查找原始队列最高职位:

public JobRequest closestDeadlineJob(int freeCPUS) { 
     // find top job to determine if other jobs for date need to be considered 
     JobRequest nextJob = scheduledJobs.peek(); // return top most job 

     if (nextJob != null) { 

      System.out.println("Found top EDF job:"); 
      printJob(nextJob); 

      // what is it's date? 
      Date highestRankedDate = nextJob.getConvertedDeadlineDate(); 

      // create a temporary queue to work out priorities of jobs with same deadline 
      JobPriorityQueue schedulerPriorityQueue = new JobPriorityQueue(); 

      // add the top job to priority queue 
      //schedulerPriorityQueue.addJob(nextJob); 

      for (JobRequest jr : scheduledJobs) { 

       // go through scheduled jobs looking for all jobs with same date 
       if (jr.getConvertedDeadlineDate().equals(highestRankedDate)) { 
        // same date deadline, soadd to scheduler priority queue 
        schedulerPriorityQueue.addJob(jr); 
        System.out.println("Adding following job to priority queue:"); 
        printJob(jr); 
       } 
      } 

      JobRequest highestPriorityJob = schedulerPriorityQueue.poll(); 
      // this is the item at the top of the PRIORTY JOB queue to return 

      // remove that item from scheduledJobs 
      scheduledJobs.remove(highestPriorityJob); 


      return highestPriorityJob; 
     } else { 
      return null; 
     } 
    } 

下面的代码来处理最高职位为队列:

public void processNextJob() { 
     /* 
     * 1. get # of free CPU's still avaialble 
     * 2. get top most job from priority queue 
     * 3. run job - put to CPU queue 
     * 4. develop a CPU queue here 
     * 5. count cores against freeCPUS and some sort of calculation to sort run times 
     */ 
     int freeCPUS = 500; 
     int availableCPUS = 0; 
     Queue q = new PriorityQueue(); 

//  while(freeCPUS >= 500) 
//  { 
//   
//  } 


     JobRequest nextJob = schedulerPriorityQueue.closestDeadlineJob(freeCPUS); // returns top job from queue 
     if (nextJob != null) { 
      System.out.println("Top priority/edf job:"); 
      System.out.print(nextJob.getUserID() + "-->"); 
      System.out.print(nextJob.getStartDate() + "--START-->"); 
      System.out.print(nextJob.getEndDate() + "---END-->"); 
      System.out.print(nextJob.getDeadDate() + "--DROP-->"); 
      System.out.print(nextJob.getDepartment() + "-->"); 
      System.out.print(nextJob.getProjectName() + "-->"); 
      System.out.print(nextJob.getProjectApplication() + "-->"); 
      System.out.print(nextJob.getPriority() + "--PRIORITY-->"); 
      System.out.print(nextJob.getCores() + "-->"); 
      System.out.print(nextJob.getDiskSpace() + "-->"); 
      System.out.println(nextJob.getAnaylsis()); 

      // now got correct job based on earliest deadline/priority 
      // implement a FIFO queue here/execution stack 
      // add next job here 
     } else { 
      System.out.println("Job = null"); 
     } 

    } 

我需要做的是解决我的可怜的企图或改编,在将工作从什么我最近的DeDeline工作进入队列,然后当我达到我的500核心限制时停止将它们放入队列中。目前我只是被困在while循环下面的for循环中,我不认为我离开循环后我已经设置的方式甚至会工作。

有什么想法?

编辑

public void processNextJob() { 
     /* 
     * 1. get # of free CPU's still avaialble 
     * 2. get top most job from priority queue 
     * 3. run job - put to CPU queue 
     * 4. develop a CPU queue here 
     * 5. count cores against freeCPUS and some sort of calculation to sort run times 
     */ 
     int freeCPUS = 500; 
     int availableCPUS = 0; 

     JobRequest nextJob = schedulerPriorityQueue.closestDeadlineJob(freeCPUS); // returns top job from queue 
     if (nextJob != null) { 
      System.out.println("Top priority/edf job:"); 
      printJob(nextJob); 
      // go through scheduled jobs looking for all jobs with same date 
      if (nextJob.getCores() <= freeCPUS) { 
       // same date deadline, soadd to scheduler priority queue 
       schedulerPriorityQueue.addJob(nextJob); 
       System.out.println("Adding following job to execution queue:"); 
       printJob(nextJob);  
       // can use this to get the next top job but need to add calculations to printout the next top job aslong as CPU less than 500 
//    schedulerPriorityQueue.closestDeadlineJob(freeCPUS); 
//    schedulerPriorityQueue.addJob(nextJob); 
      } else if (nextJob.getCores() > freeCPUS) { 
       System.out.println("Queue temporarily full"); 
      } 
      // now got correct job based on earliest deadline/priority 
      // implement a FIFO queue here/execution stack 
      // add next job here 
     } else { 
      System.out.println("Job = null"); 
     } 

    } 

我想我需要实现上述一个循环,并搬出if语句说再次参加接下来的工作,如果低于500,循环并得到另一个然后把它变成一个新的队列某种,当满足500核心标准时,停止添加到新队列

+1

没有真正回答这个问题,但有一个原因,你不能做在SQL中的数据的多个过滤? – SimonC 2013-02-21 14:13:23

+0

另外,当所有500(!)核心都忙时应该是什么样的行为?新工作应该被拒绝还是排队? – SimonC 2013-02-21 14:20:28

+0

由于约束条件以及事物设置为否,我只需将“x”个工作量添加到队列中(不知道哪种类型是最好的),即核心限制低于500并且无法再添加从队列中或已满,然后停止添加,直到空间变为空闲。他们将留在原来的队列,直到空间变得可用,把他们放在“执行队列”,我试图在这里设置 – 2013-02-21 14:21:40

回答

1

找到解决我的问题:

public void processNextJob() { 
     /* 
     * 1. get # of free CPU's still avaialble 
     * 2. get top most job from priority queue 
     * 3. run job - put to CPU queue 
     * 4. develop a CPU queue here 
     * 5. count cores against freeCPUS and some sort of calculation to sort run times 
     */ 
     int freeCPUS = 500; 
     int availableCPUS = 0; 
     JobRequest temp = new JobRequest(); 
     Queue q = new LinkedList(); 

     while (true) { 
      int size = q.size(); 
      for (int i = 0; i < size; i++) { 
       temp = (JobRequest) q.peek(); 
       if (temp != null) { 
        availableCPUS += temp.getCores(); 
       } 
      } 
      if ((freeCPUS - availableCPUS) >= 0) { 
       JobRequest nextJob = schedulerPriorityQueue.closestDeadlineJob(freeCPUS - availableCPUS); // returns top job from queue 
       if (nextJob != null) { 
        System.out.println("Top priority/edf job:"); 
        printJob(nextJob); 
        q.add(nextJob); 

       } else { 
        System.out.println("Job = null"); 
       } 

      } else { 
       break; 
      } 
     } 
     if (temp != null) { 


      System.out.println("Execution Queue"); 
      System.out.println(q); 

     } 


    } 
1

我会尽可能使用java.util.concurrent包中的实用程序。

开始时,您可以同时定义了Comparator按日期则优先级排序,你的职位PriorityBlockingQueue,所以用的最早日期的工作和最高的优先级总是在队列的开始:

PriorityBlockingQueue<JobRequest> q = new PriorityBlockingQueue<Test1.JobRequest>(0, new Comparator<JobRequest>() 
    { 
    @Override 
    public int compare(JobRequest o1, JobRequest o2) 
    { 
     int dateComparison = o1.getDate().compareTo(o2.getDate()); 
     if (dateComparison != 0) 
     return dateComparison; 
     // assume higher number means higher priority 
     return o2.getPriority() - o1.getPriority(); 
    } 
    }); 

我仍然不确定我是否了解您对核心的要求,但您有两个选择。如果你想达到500人同时执行,则拒绝新的项目,你可以使用一个执行者与SynchronousQueue

ExecutorService executor = new ThreadPoolExecutor(0 /*core size*/, 
                500 /*max size*/, 
                0 /*keep alive*/, 
                TimeUnit.SECONDS, 
                new SynchronousQueue<Runnable>()); 

另外,如果你想同时执行较少的工作,你可以当它是使用ArrayBlockingQueue该块全:

ExecutorService executor = new ThreadPoolExecutor(0 /*core size*/, 
                5 /*max size*/, 
                0 /*keep alive*/, 
                TimeUnit.SECONDS, 
                new ArrayBlockingQueue(500-5)<Runnable>()); 

然后拉作业从队列中并执行它们,处理被拒绝的执行,但是你想:

while (!isFinished) 
{ 
    JobRequest job = q.take(); 
    try 
    { 
    executor.execute(job); 
    } 
    catch (RejectedExecutionException e) 
    { 

    } 
} 

但是,如果您只想要500个同时运行的作业和后续作业排队,只需传入LinkedBlockingQueue或使用Executors上的其中一个实用程序方法(如newFixedThreadPool(int nThreads))。

+0

感谢Simon,我编辑了有关processingNextJob的第二个代码示例,目标是在这里放入一个循环,将该作业放入队列中,就像您之前提到的那样,然后计算它需要的内核数量,例如总共有500人,在完成最高工作400人后,循环回去并抓住下一个工作,需要300人,将工作添加到队列中,剩下100人离开工作岗位,去检查下一个工作,200个核心,将这个工作留在队列中,然后搜索下一个可用的需要100个,把它放到新的队列中,这会更好一些吗? – 2013-02-21 16:12:37

+0

只是为了澄清,当你谈论500个内核时,你是否真的想要一个500线程并发运行的池?或者'核心'是否意味着别的什么?如果是前者,那么你可以通过执行'executor.getMaximumPoolSize() - executor.getActiveCount()'大致了解你有多少备用线程。然后,您可以遍历'q'并移除具有小于可用线程数的'getCoreRequirement'的第一个作业。如果你能解释这个设计背后的动机,这可能会有帮助吗? – SimonC 2013-02-21 22:21:41

+0

不,内核只是数据库中表的名称,它只是一个工作的标准值,我在原始问题上添加了一个编辑,现在我只需要它将顶部顶部添加到队列中并保留添加下一个顶级工作和下一个顶级工作,直到满足500条件,所以我想象一个while循环,然后放入一个队列来保存工作,然后计算剩余的数量,但不确定如何去做,这是一个额外的函数我正在尝试实施我已经开展的一个小项目 – 2013-02-22 18:36:43