我使用java在csma/cd中实现了1-persistent。但不知怎么经过一番反复之后。我的代码进入死锁或饥饿状态。有人能帮我摆脱困境吗?下面是这个理论的wiki链接。它适用于某些循环或更小的通道计数。
eg-5个通道,其中通道有3个帧向死锁/饥饿发送make。而4个2/1帧的频道效果很好(因为我很幸运)。
持久.java
class Persistent implements ChannelConstants {
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
PChannel.channelStatus = FREE; //initially channel is free
System.out.println("Enter number of stations");
int numberOfStations = sc.nextInt();
PChannel[] channels= new PChannel[numberOfStations+1];
int[] noOfFramesInChannel = new int[numberOfStations+1];
/* try {
Files.delete(Path.of("log.txt"));
} catch (IOException e) {
System.out.println("Do Nothing.");
}*/
for(int i = 1;i<=numberOfStations;i++)
{
System.out.println("Enter number of frames for Station " + i);
noOfFramesInChannel[i] = sc.nextInt();
}
FileWriter fileWriter = null;
try {
fileWriter = new FileWriter("logs.txt",true);
fileWriter.write("Started Frame writing at "+new Date()+"\n");
fileWriter.flush();
} catch (IOException e) {
e.printStackTrace();
System.exit(1);
}
for(int i = 1;i<=numberOfStations;i++)
channels[i] = new PChannel("Station "+i,noOfFramesInChannel[i],fileWriter);
try {
// wait for stations to complete transmission
for(int i=1;i<=numberOfStations;i++)
channels[i].t.join();
}
catch (InterruptedException e) {
System.out.println("Main Thread Interrupted");
Thread.currentThread().interrupt();
}
try {
fileWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("Transmission completed.");
}
}
pchannel.java文件
class PChannel implements Runnable, ChannelConstants {
String stationNumber;
Thread t;
static int distance;
static int stat=0;
static int frame;
static int channelStatus; //Indicates if channel is being used
int frameNumber;
int maxFrameNumber;
private final AtomicBoolean checkIfSuccessfulTransmission;
static int tfr=50; //Transmission time
private int numberOfAttempts;
Random rand ;
private static final Object distanceLock = new Object();
private static final Object channelUpdateLock = new Object();
private static final Object getStatLock = new Object();
FileWriter fileWriter ;
PChannel(String threadName, int maxFrameNumber, FileWriter fileWriter) {
stationNumber = threadName;
t = new Thread(this, stationNumber);
frameNumber = 1;
this.maxFrameNumber =maxFrameNumber;
checkIfSuccessfulTransmission = new AtomicBoolean();
this.fileWriter = fileWriter;
t.start();
}
public void run() {
rand = new Random();
while (!checkIfSuccessfulTransmission.get()) {
numberOfAttempts++;
while(frameNumber <= maxFrameNumber) {
if (numberOfAttempts < 15) { //15 is the maximum number of attempts
try {
if (channelStatus == INUSE) {
System.out.println(stationNumber + " is using 1 Persistent sensing, channel is busy");
synchronized (this){
try {
wait(); //***Waits forever.***
}
catch (InterruptedException e) {
System.out.println(("Interrupt"));
Thread.currentThread().interrupt();
System.exit(1);
}
}
}
else {
System.out.println(stationNumber + " is trying to transmit frame number : " + frameNumber);
if (channelStatus == FREE && distance == 0) {//Successful transmission
synchronized (getStatLock){
stat = PChannelThreads.checking(Thread.currentThread().getName());
if(stat == -1){
System.out.println("Error Setting up stat.");
System.exit(1);
}
frame = this.frameNumber;
}
synchronized (channelUpdateLock){
channelStatus = INUSE;
}
synchronized (distanceLock){
/* for (; distance < 9000000; distance++)
for(int i =0;i<1000;i++){
//simulate transmission over some distance
}*/
distanceLock.wait(1000);
//Thread.sleep(1000);
}
fileWriter.write(stationNumber + " frame " + frameNumber + " is successful.\n");
fileWriter.flush();
System.out.println(stationNumber + " frame " + frameNumber + " is successful.");
checkIfSuccessfulTransmission.set(true);
frameNumber++;
synchronized (distanceLock){
distance = 0;
}
synchronized (channelUpdateLock){
channelStatus = FREE;
}
synchronized (this){
try{
notifyAll(); ///***Notify All doesnt works.***
} catch (Exception e) {
e.printStackTrace();
}
}
}
else {//Collision has occurred
System.out.println("Collision for frame " + frameNumber + " of " +
stationNumber + " and frame " + frame + " of Station " + stat);
System.out.println("Retransmitting Station " + stat + "'s frame " + frame);
checkIfSuccessfulTransmission.set(false);
synchronized (channelUpdateLock){
channelStatus = FREE;
}
numberOfAttempts++;
try {
int anInt = rand.nextInt((int) (Math.pow(2,(double) numberOfAttempts - 1)));
int backOffTime = anInt * tfr;
Thread.sleep(backOffTime);
} catch (InterruptedException e) {
System.out.println("Interrupted");
Thread.currentThread().interrupt();
}
}
Thread.sleep(1000);
}
} catch (InterruptedException | IOException e) {
System.out.println(stationNumber + "Main Interrupted");
Thread.currentThread().interrupt();
}
}
else {
checkIfSuccessfulTransmission.set(true);
System.out.println("Too many attempts for frame " + frameNumber + "of " +
stationNumber + ". Transmission stopped");
}
}
}
}
}
pchannelthreads.java文件
public class PChannelThreads {
private PChannelThreads(){throw new UnsupportedOperationException("Util Class.");}
public static int checking(String name) {
int stat = -1 ;
try{
stat = Integer.parseInt(name.substring(8));
}catch (NumberFormatException e ){
//Some Error.
System.out.println("Channel name I got is "+name);
}
return stat;
}
}
暂无答案!
目前还没有任何答案,快来回答吧!