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

Posted

技术标签:

【中文标题】最短剩余时间优先:Java多线程【英文标题】:Shortest Remaining Time First: Java Multithreading 【发布时间】:2012-09-22 16:41:57 【问题描述】:

我正在尝试在 java 中模拟 CPU 调度算法并使用多线程。我已经成功实现了 FCFS(先到先服务)和 SJF(最短工作优先)。但问题是当我开始想到 SRTF(最短剩余时间优先)时,它是 SJF 的一种抢先形式。 我正在使用以下模型:

CPU 线程,它有一个CLOCK 变量,每100ms 保持滴答声(一个简单的时钟增量)。我有一个boolean isAvailable; 标志供进程在开始执行之前检查 CPU 是否可用。 Lo​​ng Term Scheduler (LTS) 的线程,它将进程从进程列表推送到就绪队列。 短期调度程序 (STS) 的线程,它从 ReadyQueue 中获取一个进程并将其分配给 CPU。 一旦一个进程被 STS 从 ReadyQueue 中删除以执行,该进程将检查 CPU 的 isAvailable 标志。如果true,它将标志设置为false并开始执行(为此我只是让线程休眠(100 * burstTime) ms,因为这只是一个模拟)。否则,进程只会忙于等待:while(CPU.isAvailable != true);

我事先有进程列表以及它们的到达和突发时间。 在我模拟非抢占式调度(FCFS 和 SJF)之前没关系。但是当我尝试 SRTF 时,我无法找到一种方法来抢占当前正在运行的进程线程。

对于 SRTF,我知道从 ReadyQueue 中选择下一个进程的方法。一旦我从队列中选择了一个进程,我可以尝试将isAvailable 标志设置为false,但是我如何知道最初执行的是哪个线程?由于我没有使用太多同步黑白线程,因此我将有多个使用CPU 线程的进程。它变得有点乱了。请帮忙。谢谢!

这是进程的代码:

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();
    
    

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();
            
    

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;
    

【问题讨论】:

需要显示更多代码,特别是 CPU。 我已经添加了CPU和'LTS'的代码。 while(!CPU.isAvailable());while (CPU.done!=true) 以及具有非易失性布尔值的相关条件循环 + 编译器优化 = 头痛 -- 这是什么鬼,从 2012 年开始,它是如何到达首页的 【参考方案1】:

问题 1 是您的共享状态不是线程安全的。即使像布尔值这样简单的东西也需要正确的线程原语来确保跨线程的可见性(也称为“易失性”)。

【讨论】:

您能详细说明一下吗?谢谢! 这个话题太大了,这里就不多说了。很多人推荐读这本书:amazon.com/Java-Concurrency-Practice-Brian-Goetz/dp/0321349601

以上是关于最短剩余时间优先:Java多线程的主要内容,如果未能解决你的问题,请参考以下文章

Java 多线程基础线程优先级和守护线程

Java多线程-线程调度及获取和设置线程优先级

Java基础_多线程2[线程控制]

Java多线程之线程生命周期

java 22 - 6 多线程之线程调度和设置线程的优先级

Java多线程系列--“基础篇”10之 线程优先级和守护线程