简体   繁体   English

最短剩余时间优先:Java多线程

[英]Shortest Remaining Time First: Java Multithreading

I am trying to simulate CPU scheduling algorithms in java and am using multithreading.我正在尝试在 java 中模拟 CPU 调度算法并使用多线程。 I have successfully implemented FCFS(First Come First Serve) and SJF(Shortest Job First).我已经成功实现了 FCFS(先到先服务)和 SJF(最短工作优先)。 But the problem is when i start to think of SRTF(Shortest Remaining Time First) which is a preemptive form of SJF.但问题是当我开始想到 SRTF(最短剩余时间优先)时,它是 SJF 的一种抢先形式。 I am using the following model:我正在使用以下模型:

  • A thread for CPU, which has a CLOCK variable, which keeps ticking(a simple clock increment) every 100ms . CPU 的一个线程,它有一个CLOCK变量,它每100ms保持滴答声(一个简单的时钟增量)。 I have a boolean isAvailable;我有一个boolean isAvailable; flag for the processes to check if the CPU is available before starting execution.用于进程在开始执行之前检查 CPU 是否可用的标志。
  • A thread for Long Term Scheduler(LTS), which pushes the process from the process list to a Ready Queue. Long Term Scheduler(LTS) 的线程,它将进程从进程列表推送到就绪队列。
  • A thread for Short Term Scheduler(STS), which takes a process from the ReadyQueue and assigns it to the CPU. Short Term Scheduler (STS) 的线程,它从 ReadyQueue 中获取一个进程并将其分配给 CPU。
  • Once a process is removed from the ReadyQueue by STS for execution, the process checks for the isAvailable flag of CPU.一旦一个进程被 STS 从 ReadyQueue 中删除以执行,该进程将检查 CPU 的isAvailable标志。 If true , it sets the flag to false and starts its execution (for which i am just making the thread to sleep for (100 * burstTime) ms as this is just a simulation).如果为true ,它将标志设置为 false 并开始执行(为此我只是让线程休眠(100 * burstTime) ms ,因为这只是一个模拟)。 Otherwise, the process just keeps busy waiting : while(CPU.isAvailable != true);否则,进程只会忙于等待: while(CPU.isAvailable != true); . .

I have the list of processes along with their arrival and burst times before hand.我事先有进程列表以及它们的到达和突发时间。 It is ok till i am simulatiing non-preemptive scheduling(FCFS and SJF).在我模拟非抢占式调度(FCFS 和 SJF)之前没关系。 But as i try for SRTF, I am unable to find a way to preempt the currently running process thread.但是当我尝试使用 SRTF 时,我无法找到一种方法来抢占当前正在运行的进程线程。

For SRTF, i know the way ahead to select the next process from ReadyQueue.对于 SRTF,我知道从 ReadyQueue 中选择下一个进程的方法。 I can try to set the isAvailable flag to false once i select a process from the queue, but then how am I to know which thread was originally executing?从队列中选择一个进程后,我可以尝试将isAvailable标志设置为false ,但是我如何知道最初执行的是哪个线程? And since I am not using much of synchronization b/w threads, I will have multiple processes using the CPU thread.而且由于我没有使用太多同步黑白线程,因此我将有多个进程使用CPU线程。 Its getting a little messed up.它变得有点乱了。 Please help.请帮忙。 Thanks!谢谢!

This is the code for a Process:这是进程的代码:

enum State {ARRIVED, WAITING, READY, RUNNING, EXECUTED}
public class Process implements Runnable
{
    int pid;
    int arrTime;
int burstTime;
int priority;
long startTime;
long endTime;
State procState = null;

Process(int pid, int arrTime, int burstTime, int priority)
{
    this.pid = pid;
    this.arrTime = arrTime;
    this.burstTime = burstTime;
    this.priority = priority;
    this.procState = State.ARRIVED;
    this.startTime = 0;


    this.endTime = 0;    /* I also considered adding a timeElapsedUnderExecution
 attribute to the process. So I can check after every cycle if the CPU is still available
 and keep incrementing the time elapsed. Once the timeElapsed becomes same as burstTime, i
 stop the process. Or if after a cycle, the CPU is not available, i know from where to
 resume my Process. Is this the way to go ? */

    }

boolean isReady()
{
    if((this.arrTime <= CPU.CLOCK) && (this.procState == State.ARRIVED))
        return true;
    else return false;
}

@Override
public void run() {
    // TODO Auto-generated method stub
    if(this.procState == State.READY)
        this.procState = State.WAITING;

    while(!CPU.isAvailable());

    try 
    {
        this.procState = State.RUNNING;
        System.out.println("Process " + pid + " executing...");
        this.startTime = CPU.CLOCK;
        System.out.println("Process " + this.pid + ": Begins at " + this.startTime);
        Thread.sleep(this.burstTime * 100);
        this.endTime = CPU.CLOCK;
        System.out.println("Process " + this.pid + ": Ends at " + this.endTime);
        this.procState = State.EXECUTED;

    }
    catch (InterruptedException e) 
    {
        // TODO Auto-generated catch block
        System.out.println("Interrupted: " + pid);
        e.printStackTrace();
    }
    }
}

The code for CPU: CPU的代码:

    import java.util.LinkedList;
    import java.util.Queue;

    public class CPU implements Runnable

{
    static Long CLOCK = new Long(0);
    static LinkedList<Process> ReadyQ = new LinkedList<Process>();
private static boolean isAvailable = true;
static boolean done = false;

public static boolean isAvailable() {
    return isAvailable;
}

public static void setAvailable(boolean isAvailable) {
    CPU.isAvailable = isAvailable;
}

static void incrementCLOCK()
{
    LTS.checkArrival();
    CPU.CLOCK++;
    try {
        Thread.sleep(100);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    System.out.println("Clock Tick: " + CPU.CLOCK);
}

@Override
public void run() {
    // TODO Auto-generated method stub
    System.out.println("CPU starts.!!!");
    while(CPU.done != true)
        synchronized(CPU.CLOCK)
        {
            incrementCLOCK();
            }
    }
}

The code for LTS: LTS 的代码:

public class LTS implements Runnable 
{
    private static Process[] pList = null;
    private final int NUM;
    static Integer procStarted;
    static Integer procFinished;
    static boolean STSDone = false;


LTS(Process[] pList, int num)
{
    this.NUM = num;
    LTS.pList = pList;
}

static void checkArrival()
{
    if(pList == null) return;
    for(int i = 0; i < pList.length; i++)
        if(pList[i].isReady())
        {
            pList[i].procState = State.READY;
            System.out.println("Process " + pList[i].pid + " is now ready.");
            CPU.ReadyQ.add(pList[i]);
        }
}

@Override
public void run() {
    // TODO Auto-generated method stub
    System.out.println("Long Term Scheduler starts.!!!");
    while(LTS.STSDone != true)
    {
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    System.out.println(LTS.STSDone);
    System.out.println("LTS ends.!!!");
        CPU.done = true;
    }
}

Problem number 1 is that your shared state is not thread-safe.问题 1 是您的共享状态不是线程安全的。 Even simple things like booleans need correct threading primitives to ensure visibility across threads (aka "volatile").即使像布尔值这样简单的东西也需要正确的线程原语来确保跨线程的可见性(又名“易失性”)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM