有一个名为busyList
的LinkedList可以跟踪所有繁忙的机器。机器可能正忙或可用。机器的id
会从列表中删除获得自由。
以下是在机器空闲/忙碌时被触发的方法
@Override
public void cloudSimEventFired(CloudSimEvent e) {
if(e.getId() == CloudSimEvents.EVENT_CLOUDLET_ALLOCATED_TO_VM) {
int vmId = (Integer) e.getParameter(Constants.PARAM_VM_ID);
busyList.add(vmId);
}else if(e.getId() == CloudSimEvents.EVENT_VM_FINISHED_CLOUDLET) {
int vmId = (Integer) e.getParameter(Constants.PARAM_VM_ID);
busyList.remove(new Integer(vmId));
}
}
名为allMap
的地图(用于分配地图)将机器的ID作为其键,并将class VmAllocation
的对象作为其值。VmAllocation
的属性为:
maxAlloc (which tells the maximum times a machine can be returned)
currAlloc (which tells the current count)
/*
allMap.put(id, new VmAllocation(o.getMemory()/512, 0));
o.getMemory()/512 => maxAlloc
0 => currAlloc
This map has been initialized earlier.Like for 3 machines id will be 0,1,2
As the machine will be returned currAlloc will be incremented by 1
but it cannot exceed maxAlloc.
*/
我必须以循环方式返回机器,同时保持视野,我不会返回当前忙碌的机器。如果busyList.contains(id)
返回true,则表示机器正忙,并且返回下一个可用的机器(在allMap中),同时保持视图不会超过maxAlloc
设置。例如,如果1
忙碌,如果2
不忙且2
未超过currAlloc
maxAlloc
以下是必须返回机器的方法,并且从封闭类外部多次调用。
@Override
public int getNextAvailableVm() {
// return the id
}
这是算法应用的一般方法:
Let the id of the machines inside the allMap be :
0,1,2,3,4
0 has maxAlloc of 4
1 has maxAlloc of 4
2,3 has maxAlloc of 2
4 has maxAlloc of 1
The ideal order of returning will be :
0000 1111 22 33 4 0000 1111 22 33 4 00....
但是只有当机器都没有忙时才会发生这种情况。但如果机器忙碌,订单可能就像:
0 0 1 2 0 1 0 1 ....
请注意,返回计算机的次数不能超过maxAlloc
,如果发现计算机忙于将要返回的下一台计算机,那么该计算机可能就在当前正忙的计算机旁边本身不忙(还有currAlloc不应超过maxAlloc)
如果maxAlloc = 5,则currAlloc限制为4.因为其计数从0开始
我无法实现此逻辑。帮我这样做。
答案 0 :(得分:1)
应该适合您的代码的函数如下:
public Integer getNextAvailable() {
Integer machineId = null;
VMallocation allocation;
// busyListIsFull is a volatile variable that has to be shared between the 2 classes:
// the one that contains getNext... and the one that modifies busyList
//this should be added to the code that modifies busyList
/*
if(busyList.containsAll(mapAll.keySet())) {
busyListIsFull = true;
notifyAll();
}
*/
// all machines are busy
while(busyListIsFull) {
try {
wait();
} catch (InterruptedException e) {
}
}
busyListIsFull = false;
notifyAll();
for(Map.Entry<Integer, VMallocation> entry: mapAll.entrySet()) {
machineId = (Integer)(entry.getKey());
allocation = (VMallocation)(entry.getValue());
// allocate the next machineId if it is not busy and has available allocations
if(!busyList.contains(machineId) &&
allocation.getCurrentAlloc() < allocation.getMaxAlloc()) {
System.out.println("allocating machineId:" + machineId);
allocation.setCurrentAlloc(allocation.getCurrentAlloc() + 1);
if(machineId != null) {
return machineId;
}
}
}
// no machineId was returned if code execution gets here, so no
//resource was available; now free them all
for(Map.Entry<Integer, VMallocation> entry: mapAll.entrySet()) {
allocation = (VMallocation)(entry.getValue());
allocation.setCurrentAlloc(0);
}
// return first available machine
return getNextAvailable();
}
答案 1 :(得分:1)
我对你的问题很感兴趣,所以我提出了这个可能适合你的解决方案。该代码中没有健全性检查,它只是一个概念证明。
事件:
public class CloudSimEvent {
private final int id;
private final boolean allocated;
public CloudSimEvent(int id, boolean allocated) {
super();
this.id = id;
this.allocated = allocated;
}
public int getID() {
return id;
}
public boolean allocated() {
return allocated;
}
public boolean finished() {
return !allocated;
}
}
活动界面
public interface CloudSimEventListener {
public void cloudSimEventFired(CloudSimEvent e);
}
VMAllocation对象
public final class VMAllocation implements Comparable<VMAllocation> {
private final int id;
private final int maxAlloc;
private final int currAlloc;
public VMAllocation(int id, int maxAlloc, int currAlloc) {
super();
this.id = id;
this.maxAlloc = maxAlloc;
this.currAlloc = currAlloc;
}
public VMAllocation allocate() {
return new VMAllocation(id, maxAlloc, currAlloc + 1);
}
public VMAllocation finish() {
return new VMAllocation(id, maxAlloc, currAlloc - 1);
}
public boolean isBusy() {
return currAlloc >= maxAlloc;
}
public int getId() {
return id;
}
@Override
public int compareTo(VMAllocation o) {
if (isBusy() && !o.isBusy()) {
return 1;
} else if (!isBusy() && o.isBusy()) {
return -1;
} else {
return Integer.compare(id, o.id);
}
}
@Override
public String toString() {
return "id: " + id + " currAlloc: " + currAlloc + " maxAlloc: "
+ maxAlloc + " is-busy: " + isBusy();
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + currAlloc;
result = prime * result + id;
result = prime * result + maxAlloc;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
VMAllocation other = (VMAllocation) obj;
if (currAlloc != other.currAlloc)
return false;
if (id != other.id)
return false;
if (maxAlloc != other.maxAlloc)
return false;
return true;
}
}
RRScheduler
import java.util.Arrays;
import java.util.Iterator;
import java.util.PriorityQueue;
public class RRSheduler implements CloudSimEventListener {
private final PriorityQueue<VMAllocation> queue = new PriorityQueue<>();
public void addVMAllocation(VMAllocation allocation) {
synchronized (queue) {
queue.add(allocation);
}
}
@Override
public void cloudSimEventFired(CloudSimEvent e) {
VMChanged(e.getID(), e.allocated());
}
private void VMChanged(int id, boolean allocation) {
synchronized (queue) {
Iterator<VMAllocation> it = queue.iterator();
VMAllocation newAllocation = null;
while (it.hasNext()) {
VMAllocation vmAllocation = it.next();
if (vmAllocation.getId() == id) {
if (allocation)
newAllocation = vmAllocation.allocate();
else
newAllocation = vmAllocation.finish();
it.remove();
break;
}
}
if (newAllocation != null)
queue.add(newAllocation);
}
}
public VMAllocation getNextFreeVMAllocation() {
synchronized (queue) {
VMAllocation allocation = queue.element();
return allocation.isBusy() ? null : allocation;
}
}
@Override
public String toString() {
synchronized (queue) {
VMAllocation[] arr = queue.toArray(new VMAllocation[] {});
Arrays.sort(arr);
return Arrays.toString(arr);
}
}
}
简单的测试程序
public class TestRR {
public static void main(String[] args) {
RRSheduler rrSheduler = new RRSheduler();
rrSheduler.addVMAllocation(new VMAllocation(0, 4, 0));
rrSheduler.addVMAllocation(new VMAllocation(1, 4, 0));
rrSheduler.addVMAllocation(new VMAllocation(2, 2, 0));
rrSheduler.addVMAllocation(new VMAllocation(3, 2, 0));
rrSheduler.addVMAllocation(new VMAllocation(4, 1, 0));
VMAllocation nextAllocation = null;
while ((nextAllocation = rrSheduler.getNextFreeVMAllocation()) != null) {
System.out.println(nextAllocation);
rrSheduler.cloudSimEventFired(new CloudSimEvent(nextAllocation
.getId(), true));
}
}
}
我没有像你一样使用地图,但你可能会想到如何解决你的问题。