Producer Consumer-Average Wait times not outputtin

2019-06-14 18:52发布

问题:

I am currently making a hypothetical producer consumer problem using java. The object is to have an operating system which is 1000 bytes, but only 500 bytes available to use for threads as 500 bytes have already been consumed by drivers and other operations. The threads are as follows:

  1. A thread to start a BubbleWitch2 session of 10 seconds, which requires 100 bytes of RAM per second
  2. A thread to start a Spotify stream of 20 seconds, which requires 250 bytes of RAM per second You should also take into account the fact that the operating system is simultaneously supporting system activity and managing the processor, memory and disk space of the device on which it is installed. Therefore, additionally create:
  3. System and management threads, which, together, require 50 bytes of RAM per second, and execute for a random length of time, once invoked.
  4. A thread to install a new security update of 2 KB, which will be stored to disk, and requires 150 bytes of RAM per second while installing. Assume sufficient disk capacity in the system to support this thread.

The operating system has only capacity for 200 bytes per second, therefore a larger thread such as spotify will experience delays or be forced to wait. I have used code which as far as I can tell, implements this. I am also required to generate exit times which I have done with timestamps and to calculate average waiting times for threads.

I have included code in my solution for the average waiting times with system.out.print but no matter what I do, it is not actually outputting the times at all-as if they did not exist.

I am also not sure if the buffer size limitations are working as it is a matter of milliseconds-is there any way to tell if this is working from the code below?

My main method.

   public class ProducerConsumerTest {
        public static void main(String[] args) throws InterruptedException {
            Buffer c = new Buffer();
            BubbleWitch2 p1 = new BubbleWitch2(c,1);
            Processor c1 = new Processor(c, 1);
            Spotify p2 = new Spotify(c, 2);
            SystemManagement p3 = new SystemManagement(c, 3);
            SecurityUpdate p4 = new SecurityUpdate(c, 4, p1, p2, p3);


            p1.setName("BubbleWitch2 ");
            p2.setName("Spotify ");
            p3.setName("System Management ");
            p4.setName("Security Update ");

            p1.setPriority(10);
            p2.setPriority(10);
            p3.setPriority(10);
            p4.setPriority(5);

            c1.start();
            p1.start();
            p2.start();
            p3.start();
            p4.start();

            p2.join();
            p3.join();
            p4.join();
            System.exit(0);

        }
    }


My buffer class

import java.text.DateFormat;
import java.text.SimpleDateFormat;

/**
 * Created by Rory on 10/08/2014.
 */
class Buffer {
    private int contents, count = 0, process = 0;
    private boolean available = false;
    private long start, end, wait, request= 0;
    private DateFormat time = new SimpleDateFormat("mm:ss:SSS");



    public synchronized int get() {
        while (process <= 500) {
            try {
                wait();
            } catch (InterruptedException e) {
            }
        }
        process -= 200;
        System.out.println("CPU After Process " + process);
        notifyAll();
        return contents;
    }

    public synchronized void put(int value) {
        while (process >= 1000) {
            start = System.currentTimeMillis();
            try {
                wait();
            } catch (InterruptedException e) {
            }
            end = System.currentTimeMillis();
            wait = end - start;
            count++;
            request += wait;
            System.out.println("Application Request Wait Time: " + time.format(wait));
            process += value;
            contents = value;
            notifyAll();
        }
    }
}

My security update class

import java.lang.*;
import java.lang.System;


/**
 * Created by Rory on 11/08/2014.
 */
class SecurityUpdate extends Thread {
    private Buffer buffer;
    private int number;
    private int bytes = 150;
    private int process = 0;

    public SecurityUpdate(Buffer c, int number, BubbleWitch2 bubbleWitch2, Spotify spotify, SystemManagement systemManagement) throws InterruptedException {
        buffer = c;
        this.number = number;
        bubbleWitch2.join();
        spotify.join();
        systemManagement.join();

    }

    public void run() {

        for (int i = 0; i < 15; i++) {
            buffer.put(i);
            System.out.println(getName() + this.number
                    + " put: " + i);
            try {
                sleep(1500);
            } catch (InterruptedException e) {
            }
        }
        System.out.println("-----------------------------");
        System.out.println("Security Update has finished executing.");
        System.out.println("------------------------------");
    }
}

My processor class

class Processor extends Thread {
    private Buffer processor;
    private int number;

    public Processor(Buffer c, int number) {
        processor = c;
        this.number = number;
    }

    public void run() {
        int value = 0;
        for (int i = 0; i < 60; i++) {
            value = processor.get();
            System.out.println("Processor #"
                    + this.number
                    + " got: " + value);
        }
    }
}

My bubblewitch class

import java.lang.*;
import java.lang.System;
import java.sql.Timestamp;

/**
 * Created by Rory on 10/08/2014.
 */
class BubbleWitch2 extends Thread {
    private Buffer buffer;
    private int number;
    private int bytes = 100;
    private int duration;

    public BubbleWitch2(Buffer c, int pduration) {
        buffer = c;

        duration = pduration;
    }

    long startTime = System.currentTimeMillis();
    public void run() {
        for (int i = 0; i < 10; i++) {
            buffer.put(bytes);
            System.out.println(getName() + this.number
                    + " put: " + i);
            try {
                sleep(1000);
            } catch (InterruptedException e) {
            }
        }
        long endTime = System.currentTimeMillis();
        long timeTaken = endTime - startTime;
        java.util.Date date = new java.util.Date();


        System.out.println("-----------------------------");
        System.out.println("BubbleWitch2 has finished executing.");
        System.out.println("Time taken to execute was " +timeTaken+ " milliseconds");
        System.out.println("Time Bubblewitch2 thread exited Processor was " + new Timestamp(date.getTime()));
        System.out.println("-----------------------------");
    }
}

My system management

class SystemManagement extends Thread {
    private Buffer buffer;
    private int number, min = 1, max = 15;
    private int loopCount = (int) (Math.random() * (max - min));
    private int bytes = 50;
    private int process = 0;


    public SystemManagement(Buffer c, int number) {
        buffer = c;
        this.number = number;
    }

    public void run() {
        for (int i = 0; i < loopCount; i++) {
            buffer.put(50);
            System.out.println(getName() + this.number
                    + " put: " + i);
            try {
                sleep(1000);
            } catch (InterruptedException e) {
            }
        }
        System.out.println("-----------------------------");
        System.out.println("System Management has finished executing.");
        System.out.println("-----------------------------");
    }
}

My spotify class import java.sql.Timestamp;

/**
 * Created by Rory on 11/08/2014.
 */
class Spotify extends Thread {
    private Buffer buffer;
    private int number;
    private int bytes = 250;


    public Spotify(Buffer c, int number) {
        buffer = c;
        this.number = number;
    }


    long startTime = System.currentTimeMillis();
    public void run() {
        for (int i = 0; i < 20; i++) {
            buffer.put(bytes);
            System.out.println(getName() + this.number
                    + " put: " + i);
            try {
                sleep(1000);
            } catch (InterruptedException e) {
            }
        }

        long endTime = System.currentTimeMillis();
        long timeTaken = endTime - startTime;
        java.util.Date date = new java.util.Date();
        System.out.println(new Timestamp(date.getTime()));


        System.out.println("-----------------------------");
        System.out.println("Spotify has finished executing.");
        System.out.println("Time taken to execute was " + timeTaken + " milliseconds");
        System.out.println("Time that Spotify thread exited Processor was " + date);

        System.out.println("-----------------------------");


    }
}

I may need to add timestamps to one or two classes yet but does anyone have any idea how to get my average times to actually print out? Or what is preventing it and if the buffer limitation is effectively being shown here(given that we are talking about milliseconds?) Thanks.

回答1:

The reason why sys out's are not printing is because of the below condition in your buffer class:-

public synchronized void put(int value) {
        while (process >= 1000) {
            .....
            notifyAll();
        }
}

this condition never gets satisified as the process never is greater than 1000

This is the reason why your Processor thread also gets stuck because when it calls get() it finds that the process is less than 500 and hence it indefinitely waits when it reaches the wait() line of code.

Rectifying the process condition appropriately in your put should let your missing sys out get printed

public synchronized void put(int value) {
        if(process <= 500) {
            process+=value;
        } else {
            //while (process >= 1000) {
                start = System.currentTimeMillis();
                try {
                    wait();
                } catch (InterruptedException e) {
                }
                end = System.currentTimeMillis();
                wait = end - start;
                count++;
                request += wait;
                System.out.println("Application Request Wait Time: " + time.format(wait));
                process += value;
                contents = value;               
            //}
        }
        notifyAll();
    }


回答2:

If you want securityupdate thread to always run at the last then the correct way of using join within that thread is as below:-

class SecurityUpdate extends Thread {
    private Buffer buffer;
    private int number;
    private int bytes = 150;
    private int process = 0;
    private BubbleWitch2 bubbleWitch2;
    private Spotify spotify;
    private SystemManagement systemManagement;

    public SecurityUpdate(Buffer c, int number, BubbleWitch2 bubbleWitch2, Spotify spotify, SystemManagement systemManagement) throws InterruptedException {
        buffer = c;
        this.number = number;
        this.bubbleWitch2 = bubbleWitch2;
        this.spotify = spotify;
        this.systemManagement = systemManagement;
    }

    public void run() {

        try {
            bubbleWitch2.join();
            spotify.join();
            systemManagement.join();
        } catch (InterruptedException e) {      
        }
        System.out.println("Finally starting the security update");
        for (int i = 0; i < 15; i++) {
            buffer.put(bytes);  // Paul check if it should be i or bytes
            System.out.println(getName() + this.number
                    + " put: " + i);
            try {
                sleep(1500);  // Paul why is this made to sleep 1500 seconds?
            } catch (InterruptedException e) {
            }
        }
        System.out.println("-----------------------------");
        System.out.println("Security Update has finished executing.");
        System.out.println("------------------------------");
    }
}