java优先级队列到队列适配

时间:2013-02-21 12:53:46

标签: java queue priority-queue

我有一个优先级队列,按日期顺序列出sql数据库中的多个作业。然后,我获得了下面最接近的DeadJob函数,它获得了最高职位,检查是否有任何其他工作具有相同的日期,然后比较优先级以查看哪个是最重要的工作。然后我得到了最高职位。

查找原始队列最高职位:

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");
        } 

    }

我需要做的是修复我的不良尝试或适应将我的nearestDeadlineJob中的作业放入队列,然后在达到我的500核心限制时停止将它们放入队列。目前我刚刚陷入了for循环之下的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个核心条件时停止添加到新队列

2 个答案:

答案 0 :(得分:1)

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

首先,您可以使用PriorityBlockingQueue定义Comparator,按日期和优先级对作业进行排序,因此具有最早日期和最高优先级的作业始终位于队列的开头:

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)

答案 1 :(得分: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);

        }


    }