実際、私はJavaスレッドの分野では初めてです。リアルタイムシステムのEarliest Deadline First Scheduling Algorithmを実装したいと考えています。次のタスクのコードを生成しました。 1. タスクは 1 秒ごとに生成されます。// Main.java
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Random;
public class Main
{
public static void main(String args[])throws Exception
{
Node node;
Random rand = new Random();
int Threshold = 10;
long Period,Deadline,Duration;
System.out.println("Task Generation Starts....\n");
System.out.println(Thread.currentThread().getName()+ " START\n");
for(int i =1;i<=Threshold;i++)
{
Calendar c = new GregorianCalendar();
long m = c.get(GregorianCalendar.SECOND);
Duration = rand.nextInt(4)+1;
Period = rand.nextInt(10)+1;
Deadline = Period + m;
node = new Node("Task"+i, m, Duration, Period, Deadline);
new Tasks("Task"+i,node);
Thread.sleep(1000);
}
System.out.println(Thread.currentThread().getName()+ " STOP\n");
}
}
- このタスクは、Runnable を実装する 1 つのタスク クラスに渡されます。
// Tasks.java
import java.util.logging.Level;
import java.util.logging.Logger;
import java.lang.Thread;
class Tasks implements Runnable
{
Thread T;
String taskname;
Node task;
TaskPriority taskpriority = new TaskPriority();
public Tasks(String S,Node newtask)
{
this.taskname=S;
this.task = newtask;
T = Thread.currentThread();
T.setName(taskname);
T = new Thread(this, T.getName());
System.out.println(T.getName()+ "Starts Running");
T.start();
}
public void run()
{
try
{
taskpriority.insert(task);
taskpriority.pop();
}
catch(InterruptedException ie)
{
Logger.getLogger(Tasks.class.getName()).log(Level.SEVERE,"error is"+ie.getMessage(),ie);
}
}
}
- Tasks.java から taskpriority.java の挿入関数が呼び出され、その直後に、Earliest Deadline 関数クラスを呼び出す pop() 関数が呼び出されます。
- 私が欲しいのは
最大優先度の最初のスレッドが実行のために到着します。指定されたスレッドには次の詳細があります。 Task ArrivalTime WCET Period(Cycle) Deadline Task1 38 4Sec. 6 44 秒
タスクの実行は 38 秒で開始されます。最悪の場合の実行時間 (WCET) は 4 秒です。Task1 は 38 秒で開始し、1 秒間実行し、残り (4-1=3 秒) を計算します。この 1 秒間の実行後、スケジューラは他のタスクが到着するかどうかを確認します。2 番目のタスクが 39 秒に到着した場合。Task ArrivalTime WCET Period(Cycle) 締め切り Task2 39 4Sec. 5 44 秒
ここで、EDF は両方のタスクの期限を達成するために残された時間をチェックします: Task1 (Task1 の実際の到着時間は 38 ですが、実行の 1 秒後には 39 になります) (44-39 = 5 秒) および Task2 (44-39=5 秒) .) 古いタスクが続行され、さらに 1 秒後、つまり 40 秒後に再び実行されます。EDF スケジューラーは 1 秒後に再度チェックします。Task3 が到着しました。Task ArrivalTime WCET Period(Cycle) 締め切り Task3 40 2Sec. 5 45 秒
ここで、タスク 1 が実行しているすべてのタスクの締め切りに到達するまでの残り時間をもう一度確認し、4 から 2 単位の時間を完了します。したがって、タスク 1 (44-40 = 2 秒)、タスク 2 (44-39 = 5 秒)、およびタスク 3 (45-40 =5 秒)。これら 3 つのタスクすべての残り時間に基づいて、スケジューラは最大優先度を Task1 に割り当て、Task4 と Task2 を先取りします。このようにして、この与えられたアルゴリズムは今後のタスクで機能します (ここではしきい値は 10 です)。
ここでは、1 秒ごとにスレッドの優先度を変更/割り当てることができません。そして、どのスレッドが来ようとしているのかをどうやって知ることができますか。
//EDF コード
public void EarliestDF() throws InterruptedException, SecurityException
{
Calendar calendar = new GregorianCalendar();
long a = calendar.get(GregorianCalendar.SECOND);
System.out.println("Task\t\tArrivalTime\tWCET\t\tPeriod(Cycle)\t Deadline");
System.out.println( Thread.currentThread().getName()+"\t\t"+a+"\t\t"+task.duration+"Sec.\t\t"+task.period +"\t\t"+task.deadline+" Sec.");
System.out.println("\n");
Execution(task);
Calendar calendar2 = new GregorianCalendar();
long start = calendar2.get(GregorianCalendar.SECOND);
long newP = task.period-task.duration;
System.out.println(Thread.currentThread().getName() +" is waiting for next phase from :\t"+start + " Sec.");
Thread.sleep(newP * 1000);
Calendar calendar3 = new GregorianCalendar();
long stop = calendar3.get(GregorianCalendar.SECOND);
System.out.println(task.taskname +" execution arrive again at:\t"+stop + "Sec.");
System.out.println("\n");
System.out.println(Thread.currentThread().getName()+"is in Process again\t");
newQ();
}
public void Execution(Node task) throws InterruptedException
{
if(task.Arrival+task.duration<=task.deadline)
{
System.out.print("Execution of"+Thread.currentThread().getName()+"has started at ");
Calendar calendar2 = new GregorianCalendar();
long start = calendar2.get(GregorianCalendar.SECOND);
System.out.print(start+" Sec.\n");
while (time<=task.duration)
{
Thread.sleep(1000);
System.out.println(time+" Sec...");
task.duration=task.duration-time;
System.out.println("Time Left"+ task.duration);
task.Arrival = start + time;
System.out.println("Task " + Thread.currentThread().getName());
System.out.println("\n");
time++;
}
Calendar calendar1 = new GregorianCalendar();
long stop = calendar1.get(GregorianCalendar.SECOND);
System.out.println("Total Completion Time of"+Thread.currentThread().getName() + "is:\t"+stop+" Sec.");
}
}
このコードから、結果を1つずつ取得していません....スレッドの優先度が最大の場合、最小優先度のスレッドをプリエンプトする必要があります。優先順位をスレッドに割り当てることができません。これが私の主な問題です。