死锁/启动(等待并全部通知)

x7yiwoj4  于 2021-07-11  发布在  Java
关注(0)|答案(0)|浏览(361)

我使用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;
    }
}

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题