This is my Question
A health center has employed two doctors that examine and treat at most 25 patients in a day.
A patient is examined and treated by any one of the two doctors. Each patient has to register his name so that the doctors can examine and treat the patient on first-come-first-serve bases.
Exercise 2
Part a: For the scenario2 mentioned above, develop a program that creates patients and doctors (both are threads). Patients register in a queue and the doctors pick patient from the same queue on first-come-first-serve bases and examine and treat them. Use the queue that is not thread safe (For example ArrayDeque). Make sure your program has no synchronization issues.
Part b: Use the queue that is thread safe (For example, ArrayBlockedQueue) and check if your solution has synchronization issues. (Make sure that you solution does not provide synchronized methods or synchronized blocks)
This is my CODE
package lab8;
import java.util.ArrayDeque;
public class LAB8 {
class Doctor implements Runnable {
private String name;
private Patient patient;
Doctor (String n){
name = n;
}
public void examine (){
System.out.println("Doctor is now examining the patient");
}
public void treat(){
System.out.println("Doctor is now treating the patient");
}
#Override
public void run (){
}
}
static class Patient implements Runnable {
private String name;
Patient (String n){
name = n;
}
public void register(String name){
System.out.println(name + " is registering in Queue");
}
#Override
public void run(){
ArrayDeque<Patient> Patients = new ArrayDeque(25);
for(int i = 0;i<25;i++){
Patients.add(new Patient("Patient No " + i));
Patients.removeFirst().register("Patient No " + i);
}
}
}
public static void main(String[] args) {
ArrayDeque<Patient> Patients = new ArrayDeque(25);
for(int i = 0;i<25;i++){
(new Thread (Patients.removeFirst())).start();
}
}
}
This is the error I am getting when I run it.
Exception in thread "main" java.util.NoSuchElementException
at java.util.ArrayDeque.removeFirst(ArrayDeque.java:278)
at lab8.LAB8.main(LAB8.java:50)
Java Result: 1
I am only trying Part A right now.
In your main function, the Patients ArrayDeque object has no Patient objects. Rather it is empty, so there is nothing to remove from the queue. You need to add some Patients first.
ArrayDeque<Patient> Patients = new ArrayDeque(25);
for(int i = 0;i<25;i++){
(new Thread (Patients.removeFirst())).start();
}
You would need to add new Patients to the Patients ArrayDeque first like you do here.
Patients.add(new Patient("Patient No " + i));
So you have have something like this...
public static void main(String[] args) {
ArrayDeque<Patient> Patients = new ArrayDeque(25);
for(int i = 0;i<25;i++){
Patient p = new Patient("Patient No " + i);
(new Thread (p)).start();
Patients.add(p);
}
}
Related
I am new to JAVA and am attempting to call a method from a class that prints out a message using the same method within another class. I am very new to java and really want to learn.
What I want to do is call the getAllCustomerInfo() method from the CustomerInfo{} class which is being called from the Customer class. When I try to run the code I get the error:
Exception in thread "main" java.lang.Error: Unresolved compilation problem:
Cannot make a static reference to the non-static field c
If I make c static (static Customer c = new Customer();) and try to run my code it only prints the commas out from the getAllCustomerInfo() method and not the getName(), getAddress etc information.
Any ideas? Thank you.
CLASS 1:
public class Customer {
//Assume I have getters and setters and fields
//Method I want to use in another class
public String getAllCustomerInfo() {
String message =
getName() + "\n" +
getAddress() + "\n" +
getAge();
System.out.println(message);
return message;
}
} //END OF CUSTOMER CLASS
CLASS2:
//Class I am trying to call method from
public class CustomerInfo {
Customer c = new Customer();
public static void main(String args[]) {
//Code where I am trying to access the method from the Customer class
while (choice.equalsIgnoreCase("y")) {
System.out.print("Enter a customer number: ");
int customerNumber = sc.nextInt();
String customerInformation = sc.nextLine();
// get the Product object
Customer customer = CustomerDB.getCustomer(customerNumber);
//Check if customer exits in DB
if (customerNumber == 1) {
// display the output
System.out.println(c.getAllCustomerInfo());
} else {
System.out.println("There is no one like that in the DB.");
}
// see if the user wants to continue
System.out.print("Continue? (y/n): ");
choice = sc.nextLine();
System.out.println();
}
}
}
In the CustomerInfo class, c is a instance variable which will not exist without an object instance of CustomerInfo class. Since you are referring it from static context you will get such error. You have to make c variable static or move it inside the main method.
public class CustomerInfo{
static Customer c = new Customer();
public static void main(String args[]) {
// your implementation
}
}
OR
public class CustomerInfo{
public static void main(String args[]) {
Customer c = new Customer();
// your implementation
}
}
I am trying to add a new train to my arraylist but upon adding the train, the existing content of the arraylist gets overwritten by the new input. This results in having only one item in the arraylist without being able to add more without overwriting the other. As I do not quite know what the source of this problem in the code is, I came looking for help here.
Within this class the train is being made:
public class RCommand extends RBaseListener {
Company mycompany = new Company("traincompany");
#Override
public void enterNewtraincommand(RParser.NewtraincommandContext ctx) {
System.out.println("Now creating new train " + ctx.getText());
mycompany.addTrainTo(new Train(ctx.getChild(2).toString()));
System.out.println(mycompany.getTrains().size());
}
}
In this class the train is supposed to be added to the list.
public class Company{
private String name;
List<Train>trains = new ArrayList<Train>();
public void addTrainTo(Train train) {
trains.add(train);
for (Train t :trains) {
System.out.println(t.getName());
}
}
}
Simply test for your class Company to see if if work
public class Test {
Company company = new Company();
public static void main(String[] args) {
Test test = new Test();
test.start();
}
private void start() {
System.out.println("IT work");
company.addTrainTo(new Train("One"));
System.out.println("End first add");
company.addTrainTo(new Train("two"));
System.out.println("End second add\n");
System.out.println("Follow example will not work");
company = new Company();
company.addTrainTo(new Train("One"));
System.out.println("End first add");
company = new Company(); // <--- create the ERROR
company.addTrainTo(new Train("two"));
System.out.println("End second add");
}
}
Suppose we have train as is:
public class Train {
private String name;
public Train(String name) {
this.name = "Train" + name;
}
public String getName() {
return name;
}
}
Output is:
IT work
Train One
End first add
Train One
Train two
End second add (it work fine)
Follow example will not work
Train One
End first add
Train two
End second add<- we miss the first train because we recreate the company instance
So it work.
So the error is not in this class Company.
Check if the caller of Company recreate the class Company before adding new train
Check class train if it has something strange (static attribute for name or similar)
Looks like new "trains" object is being created for each addition. After adding, try to print the address of "trains" object to find out for sure. You can print the address by System.out.println("trains address is: " + trains)
You did't pass for us all your code required but I think, you should create a Company constructor with your train List.
Something like that:
public class Company{
private String name;
List<Train>trains;
public Company(String name, List<Train> trains){
this.name = name;
this.trains = trains;
}
...
}
Then in your RCommand class use your new Constructor
Company mycompany = new Company(new ArrayList<Train> ,"traincompany");
And it will be fine. Your mistake in code is creating new trains list every time by calling new operator.
When i try to compile an aggregation program , i receive an error saying "class,interface,enum expected". Here is my code. please help me solve this issue.
class employee
{
private String name;
private String address;
private float salary;
public employee(String na, String add,float sal)
{
name = na;
address = add;
salary = sal;
}
public void showEmpDetails()
{
System.out.println("Name " + name);
System.out.println("Address " + address);
System.out.println("Salary " + salary );
System.out.println();
}
}
import java.util.vector;
class company
{
private String comname;
private vector vt;
public company(String na)
{
comname = na;
vt = new vector();
}
public void addEmployee(employee e)
{
vt.addElement(e);
}
public void showComDetails()
{
System.out.println("Company Name " + comname);
int x = vt.size();
int y = 0;
while(y<x)
{
object e = vt.elementAt(y);
e.showEmpDetails();
y++;
}
}
}
public class demo
{
public static void main(String[] args)
{
employee e1 = new employee("Ashan","Kandy",2000.0f);
employee e2 = new employee("Steve","California",2500.0f);
employee e3 = new employee("Elon","South Africa",2500.0f);
company c1 = new company("Apple");
c1.addEmployee(e1);
c1.addEmployee(e2);
c1.addEmployee(e3);
c1.showComDetails();
}
}
Note:- i receive only one error. and also can anybody tell me why can't i have more than one public class in java.
Well, your code has more than one error actually. The reason for your specific error is that import should be at beginning of the file, not in the middle.
And my understanding of why only one public class is allowed for each file is:
It makes things clearer.
By reading the class name and document to this class, you could quickly know what the whole file is used for. If we allow multiple public classes in one file, like C++, then we have to jump inside of the file to understand it.
Notice Java is a strong object-oriented language, i.e. everything in Java is Object. So when importing, you are importing a file. It would be more complicated if one file contains multiple public classes.
It simplify testing.
Each public class could have a main function. And you could run any main function of a file Demo.java simply by java Demo. This is really nice, so that you could write test code, or example of usage in main function to show other contributor how this class should be used.
There have to be other more in-depth reason for single public class in Java. But these are my perspective.
In this project the user must enter 1 or 2 hospitals but not 3 or more. So the program starts and I display a menu. If the user presses 1 he must enter a hospital(name and department). After this the program displays the menu again and the user can choose to insert another hospital.
But after that, if I choose to insert another one (which is not permitted) the program accepts it. It seems that every time InsertHospitals() is called from the main class, the value of numberofhospitals (which is a counter counting how many hospitals I entered) equals 0.
public class Hospital {
private String Name, Departments;
private char flag;
private int numberofhospitals;
private Hospital[] ListOfHospitals;
//private Patient[] ListOfPatiens;
//private Doctor[] ListOfDoctors;
//private Examination[] ListOfExaminations;
//private Folder[] ListOfFolders;
public Hospital(String Name, String Departments)
{
this.Name=Name;
this.Departments=Departments;
}
public Hospital()
{
ListOfHospitals = new Hospital[2];
//ListOfPatiens = new Patient[100];
//ListOfDoctors = new Doctor[100];
//ListOfExaminations = new Examination[100];
//ListOfFolders = new Folder[100];
}
public String getName()
{
return Name;
}
public void setname(String Name)
{
this.Name=Name;
}
public String getDepartments()
{
return Departments;
}
public void setdepartments(String Departments)
{
this.Departments=Departments;
}
public void InsertHospitals()
{
if(numberofhospitals==2)
{
System.out.println("You can give only two hospitals!");
}
else
{
String temp = sir.readString("Hospital's Name:");
Name=temp;
String temp1 = sir.readString("Hospital's departments:");
Departments=temp1;
Hospital hospital = new Hospital(Name, Departments);
ListOfHospitals[numberofhospitals]=hospital;
numberofhospitals=numberofhospitals+1;
}
}
}
Your misunderstanding something, the list of hospitals (as mentioned) should not be inside your hospital class. You have to consider your hospital class as a blueprint you are using in your application.
Which means that you need to have a list of hospitals, as a list inside your other application class (which runs the application) and the InsertHospitals method should not be in your hospital class either obviously.
As you add a new hospital in your program, you create a new hospital object and add it to the list of hospitals (fx an arraylist) your keeping as a field value.
Also posssibly make a new constructor with parameters in the hospital class so you can insert the values outside of the class.
Something like this fx.
public class MainApp {
private ArrayList<Hospital> hospitalList;
public static void main(String[] args) {
// Initialize or load it from a file or whatever here.
hospitalList = new ArrayList<Hospital>();
// your code here...
}
public void insertHospital(<insert parameters here to create a hospital>) {
Hospital newHospital = new Hospital(<insert params with new constructor>);
hospitalList.add(newHospital);
}
}
Whatever your problem, your program completely wrong. In insertHospital() your changing Name and Departments fields, and creating new Hospital with those values. When you print Hospital information all hospitals will have the same value.
Please help me with this two-part question. Here is the first part:
(Part 2: I have updated the code since - requirements have changed a
bit.)
I am trying to implement the Librarian problem in Java. The Semaphore page on Wikipedia gives the library analogy of a Semaphore. In the first part, I am trying to model this problem. In my case, I am using a [Subject Matter Expert] instead of a Room as a resource.
Suppose a library has 10 identical study rooms, intended to be used by one student at a time. To prevent disputes, students must request a room from the front counter if they wish to make use of a study room. When a student has finished using a room, the student must return to the counter and indicate that one room has become free. If no rooms are free, students wait at the counter until someone relinquishes a room.
Since the rooms are identical, the librarian at the front desk does not keep track of which room is occupied, only the number of free rooms available. When a student requests a room, the librarian decreases this number. When a student releases a room, the librarian increases this number. Once access to a room is granted, the room can be used for as long as desired, and so it is not possible to book rooms ahead of time.
The problem I am facing in my implementation is regarding association of a Student with a Subject Matter Expert. How would you do this in the following secnario? All that the SubjectMatterExpert needs to do is print the Student Id (for now).
Part 2: New requirements:
- There are fixed number of Students, SMEs, and Book Closets
- Students have certain number of Books at the beginning (presently, books are just numbers)
- SMEs add or check out books from the Boook Closet at a Student's request
- Students specify add or check out action, number of books, and the Book Closet
This is the modified (edited) Student class:
package librarysimulation;
public class Student extends Thread {
String studentId = "";
Librarian librarian = null;
int bookCount = 0;
public Student(String id, Librarian lib, int book) {
studentId = id;
librarian = lib;
bookCount = book;
}
#Override
public void run() {
System.out.println("Student " + studentId + " is requesting SME...");
librarian.requestSME();
try {
// Do something
System.out.println("Student " + studentId + " has access to an SME.");
//How do I ask the SME to add OR checkOut 'x' number of books
//from a given BookCloset?
} finally {
librarian.releaseSME();
}
}
}
This is the modified (edited) Librarian class:
package librarysimulation;
import java.util.concurrent.Semaphore;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Librarian {
public Semaphore sme;
public int bookClosetCount = 0;
public Librarian(int smeCount, int bookCloset) {
sme = new Semaphore(smeCount, true);
bookClosetCount = bookCloset;
//openLibrary(smeCount);
}
//Receive SME request from the Student here
public void requestSME() {
try {
sme.acquire();
//assign student to SME
} catch (InterruptedException ex) {
Logger.getLogger(Librarian.class.getName()).log(Level.SEVERE, null, ex);
}
}
//Release SME from the Student here
public void releaseSME() {
sme.release();//release SME
}
//Set the SME threads active (from constructor)
//i.e., when the library opens, have the SMEs ready
public final void openLibrary(int roomCount) {
for (int i = 0; i < roomCount; i++) {
SubjectMatterExpert s = new SubjectMatterExpert(String.valueOf(i));
s.start();
}
}
}
This is the modified (edited) Subject Matter Expert class:
package librarysimulation;
public class SubjectMatterExpert extends Thread {
String smeId = "";
SubjectMatterExpert(String id) {
smeId = id;
}
#Override
public void run(){
//Handle Student request
//Students specify if they are checking out books or returning books
//Students specify number of books
//Students specify which closet
//SME simply executes the method from the Book Closet instance
}
}
This is the modified (edited) Simulator class:
package librarysimulation;
public class Simulator extends Thread {
public static final int STUDENT_COUNT = 50;
public static final int SME_COUNT = 3;
public static final int BOOKCLOSET_COUNT = 10;
public static final int BOOK_PER_STUDENT_COUNT = 10;
#Override
public void run() {
//Instantiate Library//New library with 3 SMEs
Librarian lib = new Librarian(SME_COUNT, BOOKCLOSET_COUNT);
//Create students
int i = 0;
while (i < STUDENT_COUNT) {
Student s = new Student(String.valueOf(i), lib, BOOK_PER_STUDENT_COUNT);
s.start();
i++;
}
}
public static void main(String[] args) {
Simulator s = new Simulator();
s.start();
}
}
an this is the (new) Book Closet class:
package librarysimulation;
public class BookCloset {
int closetId;
int bookCount = 0;
public BookCloset(int id, int book) {
closetId = id;
bookCount = book;
}
public int addBook(int book){
return bookCount + book;
}
public int checkOutBook(int book){
int finalBookCount = bookCount - book;
//Change book count iff it makes sense to do so
if(finalBookCount >= 0)
bookCount = finalBookCount;
//If return value is -ve, handle accordingly
return finalBookCount;
}
}
In the original librarian problem you described, the problem doesn't care which student is in which room, therefore uses a simple thread safe counter (i.e. a Semaphore) to implement control of the resources. Following that description of the problem there still needs to be an alteration of your implementation. One approach is to 2 methods on the librarian class, one for requesting the SME, the other for returning it.
class Librarian {
Semaphore sme = new Semaphore(NUMBER_OF_SMES);
void requestSme() throws InterruptedException {
sme.acquire();
}
void releaseSme() {
sme.release();
}
}
class Student {
Librarian librarian;
public void run() {
libarian.requestSme();
try {
// Do something
finally {
librarian.releaseSme();
}
}
}
However if you do need to know which Student is working with which SME, then you need a different construct for managing the resources, a Semaphore is no longer sufficient. One example could be a Queue.
class Librarian {
BlockingQueue<SubjectMatterExpert> q =
new ArrayBlockingQueue<SubjectMatterExpert>(NUMBER_OF_SMES);
public Librarian() {
for (int i = 0; i < NUMBER_OF_SMES; i++)
q.put(new SubjectMatterExpert(String.valueOf(i));
}
SubjectMatterExport requestSme() throws InterruptedException {
q.take();
}
void releaseSme(SubjectMatterExpert toRelease) {
q.put(toRelease);
}
}
class Student {
Librarian librarian;
public void run() {
SubjectMatterExpert sme = libarian.requestSme();
try {
System.out.println("Student: " + this + ", SME: " sme);
finally {
if (sme != null)
librarian.releaseSme(sme);
}
}
}
It makes sense to have SMEs as threads running in a while loop. Check out some starting codes below. Also, you need to initialize the book closet somewhere at the beginning of the simulation. I don't know about the whole approach you are taking though.
package librarysimulation;
public class SubjectMatterExpert extends Thread {
String smeId = "";
SubjectMatterExpert(String id) {
smeId = id;
}
#Override
public void run(){
while(true){
//acquire a student (semaphor)
//acquire a lock (semaphor(1))
//critical region -
//Handle Student request
//Students specify if they are checking out books or returning books
//Students specify number of books
//Students specify which closet
//release yourself (semaphor - define in library)
//release lock (semaphor(1))
}
//SME simply executes the method from the Book Closet instance
}
}
Implement and double check with others in the forum. I am new here. More experienced voices may have a better say though. Hope this helps (= does not hurt) at the end.