2016-03-23 82 views
0

我想实现一个小的Java程序,它显示了进程调度的工作原理。我目前的代码如下。我遇到的问题是ProcessScheduler类的静态方法CPU.executeInstructions(Process process)firstComeFirstServed()。我的程序目前不会编译,因为它提供了不兼容的对象类型 - Java

incompatible type error: Object can not be converted to Process 

from firstComeFirstServed()

我已经设法通过将executeInstructions()参数从Process process改为Object process来进行编译,但据我所见,以前的方法签名没有任何问题。我在程序中抛出了几个System.out.println()调用来将该类打印到屏幕上,从而确认正在操作的对象是一个Process对象。有人可以解释这里发生了什么吗?我在想什么/不理解?

package processes; 

import java.util.logging.Level; 
import java.util.logging.Logger; 
import processes.ProcessScheduler.Algorithm; 

public class ProcessManager { 
    private static Thread psThread; 

    /** 
    * @param args the command line arguments 
    */ 
    public static void main(String[] args) { 
     // Create process table 
     ProcessTable pt; 
     //System.out.println("1 " + pt.getClass()); 
     // Creat Process Scheduling Thread. 
     psThread = new Thread(new ProcessScheduler(Algorithm.FIRST_COME_FIRST_SERVE, pt = new ProcessTable())); 
     System.out.println("2 " + pt.getClass()); 
     // Start Thread 
     psThread.start(); 
     System.out.println("3 " + pt.getClass()); 
     try { 
      // Add Process' to table 
      String[] instrucSet = {"sout","name"}; 
      for(int i = 0; i < 5; i++){ 
       pt.add(new Process(ProcessTable.processCounter, i + 1, 10 - i, instrucSet)); 
      } 
      Thread.sleep(4000); 
      for(int i = 0; i < 5; i++){ 
       pt.add(new Process(ProcessTable.processCounter, i + 1, 10 - i, instrucSet)); 
      } 
      Thread.sleep(2000); 
      ProcessScheduler.run = false; 

     } catch (InterruptedException ex) { 
      Logger.getLogger(ProcessManager.class.getName()).log(Level.SEVERE, null, ex); 
     } 
    } 
} 



package processes; 

public class Process { 
    private int quanta, priority, pID; 
    private String [] instructions; 


    /** 
    * Constructor for Process class. 
    * @param p_id process id 
    * @param instruction_set Instructions to be processed by the CPU. 
    * @param quanta Represents length of time (known or estimated) taken to execute process 
    */ 
    public Process(int p_id, int quanta, String instruction_set[]){ 
     // Initialise instance variables 
     this.pID = p_id; 
     this.quanta = quanta; 
     this.instructions = instruction_set; 
    } 

    /** 
    * Constructor for Process class. 
    * @param quanta Represents length of time (known or estimated) taken to execute process 
    * @param priority Represents the priority of the process, from 1 to infinity with 1 having highest priority. 
    * @param instruction_set Instructions to be processed by the CPU. 
    */ 
    public Process(int p_id,int quanta, int priority, String instruction_set[]){ 
     // Initialise instance variables 
     this.pID = p_id; 
     this.quanta = quanta; 
     this.priority = priority; 
     this.instructions = instruction_set; 
    } 

    /** 
    * @return Returns length of process, which may either be a known or estimated quantity. 
    */ 
    public int getQuanta() { 
     return quanta; 
    } 

    /** 
    * @return Returns process priority level. 
    */ 
    public int getPriority() { 
     return priority; 
    } 

    /** 
    * @return Returns process id, a unique value generated when the process is accepted onto the process table. 
    */ 
    public int getpID() { 
     return pID; 
    } 

    /** 
    * @return Returns an array holding the instructions to be processed for this process. 
    */ 
    public String[] getInstructions() { 
     return instructions; 
    } 

    @Override 
    public String toString(){ 
     return "Process ID: " + this.getpID() + ". Quanta: " + this.getQuanta() + ". Priority: " + this.getPriority(); 
    } 

} 


package processes; 

import java.util.ArrayList; 

/** 
* 
* @author dave 
*/ 
public class ProcessTable extends ArrayList { 

    // P_id counter; 
    public static int processCounter = 0; 

    public ProcessTable(){ 
     super(); 
    } 

    /** 
    * Adds the specified process to the collection and increments the processCounter 
    * @param aProcess The process to be added to the Process Table. 
    * @return Returns true if successfully added. 
    */ 
    public boolean add(Process aProcess){ 
     boolean sucessful = super.add(aProcess); 
     if(sucessful) 
      processCounter++; 
     return sucessful; 
    } 

    /** 
    * Prints the process table to console. 
    */ 
    public void displayProcessTable(){ 

     for(int i = 0; i < this.size(); i++){ 
      System.out.println(this.get(i).toString()); 
     } 
    } 
} 


package processes; 

/** 
* 
* @author dave 
*/ 
public final class CPU { 

    private CPU(){ 

    } 

    public static void executeInstructions(Process process){ 
     System.out.println(process.toString());   
    } 

} 


package processes; 

import java.util.logging.Level; 
import java.util.logging.Logger; 


/** 
* 
* @author dave 
*/ 
public class ProcessScheduler implements Runnable {  
    public static boolean run; 
    // The algorithm to be used. 
    private String alg; 
    // To hold reference to a Proces Table. 
    public static ProcessTable pt; 

    // Class constants for scheduling algorithm type. Used in class constructor. 
    // Enum for 
    public enum Algorithm {FIRST_COME_FIRST_SERVE, SHORTEST_JOB_FIRST, ROUND_ROBIN, PRIORITY_QUEUE}; 

    /** 
    * @param scheduling_algorithm Sets the scheduling algorithm to be used when 
    * @param process_table A Process Table instant that Process will be added to. 
    * passing jobs to the CPU for execution. 
    */ 
    public ProcessScheduler(Algorithm scheduling_algorithm, ProcessTable process_table){ 
     //System.out.println("4 " + pt.getClass()); 
     // Create reference Process Table 
     //pt = new ProcessTable(); 
     pt = process_table; 
     System.out.println("5 " + pt.getClass()); 
     // Start scheduling based on algorithm represented by enum in constructor arg. 
     switch(scheduling_algorithm){ 
      case FIRST_COME_FIRST_SERVE: 
       alg = "fcfs"; 
       break; 
      case SHORTEST_JOB_FIRST: 
       alg = "sjf"; 
       break; 
      case ROUND_ROBIN: 
       alg = "rr"; 
      case PRIORITY_QUEUE: 
       alg = "pq"; 
      default: 
       alg = "pq"; 
       break; 
     } 
    } 

    /** 
    * Start Scheduling processes to the CPU 
    */ 
    public void run() {   
     //boolean run = true; 
     int sleepTime = 1000; 
     //Display algorithm to screen 
     try { 
      run = true; 
      while(run){ 
       if(!pt.isEmpty()){ 
        switch (alg) { 
         case "fcfs": 
          System.out.println("6 " + pt.getClass()); 
          firstComeFirstServed(); 
          break; 
         case "sjf": 
          shortestJobFirst(); 
          break; 
         case "rr": 
          roundRobin(); 
          break; 
         case "pq": 
          priorityQueue(); 
          break; 
        } 
       } else { 
        Thread.sleep(sleepTime); 
       } 
      } 
     } catch (InterruptedException ex) { 
      Logger.getLogger(ProcessScheduler.class.getName()).log(Level.SEVERE, null, ex); 
     } 
    } 

    /** 
    * Executes all processes in Process Table on a First Come First Served 
    * basis (the order in which they were added to the collection). 
    */ 
    private void firstComeFirstServed(){ 
     System.out.println("7 " + pt.getClass()); 
     for(int i = 0; i < pt.size(); i++){ 
      CPU.executeInstructions(pt.get(i)); 
     } 

     try { 
      Thread.sleep(1000); 
     } catch (InterruptedException ex) { 
      Logger.getLogger(ProcessScheduler.class.getName()).log(Level.SEVERE, null, ex); 
     } 
    } 
    private void shortestJobFirst(){ 
     System.out.println("in SJF"); 
    } 
    private void roundRobin(){ 
     System.out.println("in RR"); 
    } 
    private void priorityQueue(){ 
     System.out.println("in PQ"); 
    } 

} 
+0

注意您对泛型的警告。 – chrylis

+0

@chrylis就我所见(并且刚刚再次检查),NetBeans没有显示任何关于泛型的警告,只是关于评论中缺少的参数。这可能与我的问题有关吗? – Dave0504

+2

我不确定;我不是NetBeans的粉丝。你正在使用枚举,直到Java 5和泛型都没有被引入,但是你扩展'ArrayList'而不指定类型,这是你的直接问题。你的add方法也值得怀疑。使用'@ Override'。 – chrylis

回答

2

正如其他人所指出的,ProcessTable应延伸ArrayList<Process>。然而,ProcessTable类根本没有太多理由存在。所有的事情都是提供一个错误地实现的计数器(不应该是静态的)和显示方法。我会删除它,只使用ArrayList<Process>

+0

谢谢。我已经扩展了ArrayList,因为我打算在类中增加更多的功能。快速的问题,为什么不应该是一个静态变量?是否因为只会有一个ProcessTable类的实例,因此我不必担心多个实例拥有不同的值(可能导致重复的ID)? – Dave0504

+0

它不能是静态*除非*只会有一个实例,即使这样它也不是必需的。那么为什么要冒这个风险?除非你确切地知道你为什么要这样做,否则不要让事情变成静态的。 – EJP

2

问题是扩展ArrayList的ProcessTable类不是通用的。 您可以通过

public class ProcessTable<E> extends ArrayList<E> { 

修改它。然后,当你实例化它,你可以指定类类型开始ProcessTable将举行内部

ProcessTable<Process> pt;

这样编译器就会知道哪些类将返回致电pt.get(i)

如果不是,则会将其视为Object。

编辑: 作为@EJP指出,更加具体到你的问题,你可能要延长与特定的类类型的ArrayList它将与

public class ProcessTable extends ArrayList<Process> 
+1

更可能他应该写'公共类ProcessTable扩展ArrayList '。 – EJP

+0

是的,更具体的问题,你是对的。 @EJP – antorqs

2

你ProcessTable定义的工作应该是这样的:

public static class ProcessTable extends ArrayList<Process>