分類:公共資源問題、公交車問題java
順序:Qseater lab, bank, doctor多線程
【飯店】app
geustdom
//yuec2 Yue Cheng package lab9; public abstract class Guest { int mealOrder; abstract void placeOrder(); }
Groupide
//yuec2 Yue Cheng package lab9; public class Group extends Guest { static int groupsServed; int mealOrder = 4; @Override void placeOrder() { groupsServed++; } }
Individualui
//yuec2 Yue Cheng package lab9; public class Individual extends Guest { //只多很多,變量也能夠繼承 static int individualsServed; int mealOrder = 1; @Override void placeOrder() { individualsServed++; } }
DynamicDinerthis
//yuec2 Yue Cheng package lab9; import java.util.LinkedList; import java.util.Queue; import java.util.Random; import static org.junit.Assert.assertTrue; public class DynamicDiner implements Runnable { Queue<Guest> guestQ = new LinkedList<>(); DynamicKitchen kitchen = new DynamicKitchen(guestQ); long startTime, endTime; static volatile boolean dinerOpen = true; int maxQLength, guestsEntered; public static void main(String[] args) { DynamicDiner dynamicDiner = new DynamicDiner(); dynamicDiner.startTime = System.currentTimeMillis(); Thread t1 = new Thread(dynamicDiner.kitchen); t1.start(); dynamicDiner.run(); try { t1.join(); } catch (InterruptedException e) { e.printStackTrace(); } dynamicDiner.printReport(); dynamicDiner.checkAssertions(); } @Override public void run() { //write your code here Random rand = new Random(); while (dinerOpen) { //註釋一下哦 int type = rand.nextInt(2); // [0,1) -> [0,2) -> [0,1] Guest g; if (type == 0) { synchronized (guestQ) { g = new Individual(); guestQ.offer(g); } } else { synchronized (guestQ) { g = new Group(); guestQ.offer(g); } } guestsEntered += 1; if (maxQLength < guestQ.size()) { maxQLength = guestQ.size(); } int interval = rand.nextInt(30) + 1; // [0,1) -> [0, 30) -> [1, 31) try { Thread.sleep(interval); } catch (InterruptedException e) { e.printStackTrace(); } if (System.currentTimeMillis() > startTime + 1000) { dinerOpen = false; } } //while以後更新 endTime = System.currentTimeMillis(); } void printReport() { System.out.println("-------------- Guests--------------"); System.out.printf("%-25s%5d%n", "Total guests entered:", guestsEntered); System.out.printf("%-25s%5d%n", "Individuals served:", Individual.individualsServed); System.out.printf("%-25s%5d%n", "Groups served:", Group.groupsServed); System.out.printf("%-25s%5d%n", "Total guests served:", kitchen.guestsServed); System.out.printf("%-25s%5d%n", "Guests declined service:", guestQ.size()); System.out.println("--------- Kitchen -----------"); System.out.printf("%-25s%5d%n", "Meals left:", kitchen.mealStock); System.out.printf("%-25s%s%n", "Closing status", (kitchen.underStock) ? "Under stock" : "Overstock" ); System.out.println("-------------- Diner -------------- "); System.out.printf("%-25s%5d%n", "Max Q length", maxQLength); System.out.printf("%-25s%,d ms%n", "Diner was open for: ", endTime - startTime); System.out.printf("%-25s$%,5d%n", "Income:", kitchen.income); System.out.println("-----------------------------------"); } void checkAssertions() { //following statements will check final numbers and throw assertion error when incorrect assertTrue(guestsEntered == Individual.individualsServed + Group.groupsServed + guestQ.size()); assertTrue(kitchen.guestsServed == Individual.individualsServed + Group.groupsServed); assertTrue((kitchen.income == (Individual.individualsServed + Group.groupsServed * 4) * kitchen.mealRate)); if (!kitchen.underStock) assertTrue(endTime - startTime > 1000); if (kitchen.underStock) assertTrue(kitchen.mealStock <= 4 ); if (endTime - startTime < 1000) assertTrue(kitchen.underStock); } }
DynamicKitchenspa
//yuec2 Yue Cheng package lab9; import java.util.Queue; import java.util.Random; public class DynamicKitchen implements Runnable { int mealStock = 175, mealRate = 6; boolean underStock; int guestsServed, income; Queue<Guest> guestQ; DynamicKitchen (Queue<Guest> guestQ) { this.guestQ = guestQ; } @Override public void run() { //write your code here Random rand = new Random(); Guest guestServing; while (DynamicDiner.dinerOpen && !underStock) { synchronized (guestQ) { guestServing = guestQ.poll(); } if (guestServing != null) { //順序? guestServing.placeOrder(); guestsServed++; //沒說啊 只能看變量有沒有被用到了 mealStock -= guestServing.mealOrder; //忘了 if (guestServing instanceof Group) income += mealRate * 4; else income += mealRate; } //good practice else { continue; } int interval = rand.nextInt(16) + 5; // [0,1) -> [0,16) -> [5, 21) try { Thread.sleep(interval); } catch (InterruptedException e) { e.printStackTrace(); } //頭一次見 if (mealStock <= 4 && !underStock) { underStock = true; if (DynamicDiner.dinerOpen) { DynamicDiner.dinerOpen = false; } } } } }
//註釋一下哦線程
int type = rand.nextInt(2); // [0,1) -> [0,2) -> [0,1]debug
int interval = rand.nextInt(30) + 1; // [0,1) -> [0, 30) -> [1, 31)
//while以後更新
endTime = System.currentTimeMillis();
//沒說啊 只能看變量有沒有被用到了
mealStock -= guestServing.mealOrder;
//忘了
if (guestServing instanceof Group)
income += mealRate * 4;
else
income += mealRate;
//good practice
else {
continue;
}
//頭一次見
if (mealStock <= 4 && !underStock) {
underStock = true;
if (DynamicDiner.dinerOpen) {
DynamicDiner.dinerOpen = false;
}
}
【Doctor-clinic】
//不出結果是無限循環,此時須要檢查循環條件:此次是沒寫count++
//多線程很難debug?呵呵呵了,儘可能吧
clinic
package practice_14_Doctors_Clinic; import java.util.LinkedList; import java.util.Queue; import java.util.Random; public class Clinic implements Runnable{ static Queue<Patient> patientQ = new LinkedList<>(); static int patientCount; static long clinicOpenTime; int maxPatientArrivalGap; public Clinic(int maxPatientArrivalGap) { this.maxPatientArrivalGap = maxPatientArrivalGap; } @Override public void run() { Random random = new Random(); int sleepTime = random.nextInt(maxPatientArrivalGap); Clinic.clinicOpenTime = System.currentTimeMillis(); //System.out.println("ClinicManager.maxPatientCount = " + ClinicManager.maxPatientCount); //run中:一直往Q里加(synchronized),而後sleep for (int i = 0; i < ClinicManager.maxPatientCount; i++) { synchronized (Clinic.patientQ){ patientQ.offer(new Patient()); } //System.out.println("p.id in clinic class = " + p.id); //System.out.println("p.endTime in clinic class = " + p.endTime); try { Thread.sleep(sleepTime); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
doctor
package practice_14_Doctors_Clinic; public class Doctor implements Runnable { int consulationTime; public Doctor(int consulationTime) { this.consulationTime = consulationTime; } @Override public void run() { //人數不足時,poll, 統計加人數,sleep while (Clinic.patientCount < ClinicManager.maxPatientCount) { // 這好像不對 Clinic.patientQ.size = 0 Patient p; synchronized (Clinic.patientQ) { p = Clinic.patientQ.poll(); } //非空必須加 if(p != null) { //System.out.println("Clinic.patientQ.size in doctor = " + Clinic.patientQ.size()); //System.out.println("p id in doctor = " + p.id); Clinic.patientCount++; p.endTime = System.currentTimeMillis(); ClinicManager.patientWaitTime += p.endTime - p.startTime; } try { Thread.sleep(consulationTime); } catch (InterruptedException e) { e.printStackTrace(); } } } }
patient
package practice_14_Doctors_Clinic; public class Patient { static int count; long startTime; long endTime; int id; Patient() { this.startTime = System.currentTimeMillis(); //要更新的變量,這裏設置成啥?沒有變量就不須要設置 // this.endTime = endTime; Patient.count++; this.id = count; } }
//要更新的變量,這裏設置成啥?完成後再改,沒有變量就不須要設置
// this.endTime = endTime;
【Qseater】
package multithreading_Qseater; public class Person { int id; //被static修飾的成員變量和成員方法獨立於該類的任何對象。也就是說,它不依賴類特定的實例,被類的全部實例共享。 static int count; //好像都這樣 Person() { id = count++; } }
package multithreading_Qseater; public class HotSeat implements Runnable{ int seatedCount = 0; @Override public void run() { Person p; //好像都是數量限制 while (seatedCount < QSeater.maxPersons) { //只同步一個Q操做 synchronized (QSeater.personQ) { p = QSeater.personQ.poll(); } //有人坐就sleep if (p != null) { try { Thread.sleep(QSeater.sitTime); System.out.printf("Person %d sitting%n", p.id); seatedCount++; } catch (InterruptedException e) { e.printStackTrace(); } } else { System.out.println("Queue not ready"); } //end if } //end while } //end run }
package multithreading_Qseater; import java.util.LinkedList; import java.util.Queue; import java.util.Scanner; public class QSeater implements Runnable { static Queue<Person> personQ = new LinkedList<>(); static int maxPersons, sitTime; int queuedCount, delay ; //run方法同樣 @Override public void run() { while (queuedCount < maxPersons) try { synchronized (QSeater.personQ) { personQ.offer(new Person()); queuedCount++; } //放也要加Delay? Thread.sleep(delay); } catch (InterruptedException e) { e.printStackTrace(); } } //啓動2個線程 public static void main(String[] args) { QSeater qs = new QSeater(); Scanner input = new Scanner (System.in); System.out.println("How many persons to seat?"); maxPersons = input.nextInt(); System.out.println("Enter delay (ms)"); qs.delay = input.nextInt(); System.out.println("How long to sit (ms)?"); sitTime = input.nextInt(); input.close(); long startTime = System.currentTimeMillis(); Thread t1 = new Thread(qs); Thread t2 = new Thread(new HotSeat()); t1.start(); t2.start(); try { t1.join(); //wait for thread to join back t2.join(); //wait for thread to join back } catch (InterruptedException e) { e.printStackTrace(); } long endTime = System.currentTimeMillis(); System.out.printf("Done in %d ms!", (endTime - startTime)); } //end main } //end QSeater
【TA】
錯的課程:
package lab8; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import java.util.ArrayList; import java.util.Collections; import java.util.LinkedList; import java.util.List; import java.util.Queue; import java.util.Scanner; public class JavaCourse implements Runnable{ List<TA> taList = new ArrayList<>(); //list of TA objects static Queue<Student> studentQ = new LinkedList<>(); // queue of Student objects static volatile boolean allDone = false; //indicator for JavaCourse to keep creating new Students int totalTAs; //used to take user input List<Thread> taThreads = new ArrayList<>(); //Contains the thread objects created for each TA int maxQLength; //stores the max Q length so far long startTime, endTime; //start and end time of this class's run() method before printReport is invoked //do not change this method public static void main(String[] args) { JavaCourse javaCourse = new JavaCourse(); Scanner input = new Scanner(System.in); System.out.println("Enter number of TAs"); javaCourse.totalTAs = input.nextInt(); for (int i = 1; i <= javaCourse.totalTAs; i++) { System.out.print("TA" + i + "\t\t"); } System.out.println("\n------------------------------------------------------------------------------"); input.close(); for (int i = 0; i < javaCourse.totalTAs; i++ ) { TA ta = new TA(); Thread t = new Thread(ta); javaCourse.taList.add(ta); javaCourse.taThreads.add(t); t.start(); } javaCourse.run(); } @Override public void run() { //write your code here startTime = System.currentTimeMillis(); while (!allDone) { Student s = new Student(); boolean sIsNull = (s == null); System.out.println("sIsNull = " +sIsNull); synchronized(JavaCourse.studentQ) { JavaCourse.studentQ.offer(s); } //放不下 //sleep for 5 seconds try { Thread.sleep(5); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } if (studentQ.size() > maxQLength) { maxQLength = studentQ.size(); } System.out.println("studentQ.size() = " + studentQ.size()); if (allDone) { for (Thread t : taThreads) { try { t.join(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } //printReport(); } endTime = System.currentTimeMillis(); TA.totalHelpTime += endTime - startTime; printReport(); } } //do not change this method void printReport() { int totalHelpTime = 0; System.out.println("-------------------------TAs---------------------------------------"); Collections.sort(taList); for (TA ta: taList) { System.out.printf("%s%2d %s %3d %s %3d %s%n", "TA", ta.taID, "helped", ta.studentsHelped, "students for", ta.helpTime, "min" ); totalHelpTime += ta.helpTime; } System.out.println("------------------------Time---------------------------------------"); System.out.printf("%-25s%5d %s%n", "Total help time: ", totalHelpTime, "min"); System.out.printf("%-25s%5d %s%n", "Max help time", totalTAs * TA.MAX_HELP_TIME, "min"); System.out.printf("%-25s%5d %s%n", "Total lapsed time: ", (endTime - startTime), "min"); System.out.println("-----------------------Students------------------------------------"); System.out.printf("%-25s%5d%n", "Total students created:", Student.totalStudentsCreated); System.out.printf("%-25s%5d%n", "Total students helped: ", Student.totalStudentsHelped); System.out.printf("%-25s%5d%n", "Max Q length: ", maxQLength); System.out.printf("%-25s%5d%n", "Students left in the Q: ", studentQ.size()); System.out.println("-------------------------------------------------------------------"); //following statements are to test console output numbers assertEquals(Student.totalStudentsCreated, studentQ.size() + Student.totalStudentsHelped); assertTrue(totalHelpTime >= totalTAs * TA.MAX_HELP_TIME); System.out.println("totalHelpTime = " + totalHelpTime); System.out.println("totalTAs = " + totalTAs); System.out.println("TA.MAX_HELP_TIME = " + TA.MAX_HELP_TIME); assertTrue(allDone); } }
//yuec2 Yue Cheng package lab8; public class TA implements Runnable, Comparable<TA>{ int taID; int studentsHelped; int helpTime; static int totalHelpTime; static final int MAX_HELP_TIME = 120; static int taCount = 0; public TA() { //從1開始要先加再給 taID = ++taCount; //taID = taCount++; } @Override public void run() { //write your code here while (helpTime < MAX_HELP_TIME && JavaCourse.allDone == false) { synchronized (JavaCourse.studentQ) { Student student = JavaCourse.studentQ.poll(); if (student != null) { int questionTime = student.askQuestion(); studentsHelped += 1; helpTime += questionTime; totalHelpTime += questionTime; try { Thread.sleep(questionTime); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(spacer(taID) + "TA" + taID + ":Student" + student.studentID + ":" + questionTime + "min"); } } if (JavaCourse.allDone == false && totalHelpTime > taCount * MAX_HELP_TIME) { JavaCourse.allDone = true; System.out.println("******* All done flag set by TA" + taID); } } } @Override public int compareTo(TA o) { //write your code here if (helpTime - o.helpTime < 0) return 1; else if (helpTime - o.helpTime > 0) return -1; else return 0; } //do not change this method String spacer(int taID) { StringBuilder spaces = new StringBuilder(); for (int i = 1; i < taID; i++) { spaces.append("\t\t"); } return spaces.toString(); } }
//yuec2 Yue Cheng package lab8; import java.util.Random; public class Student { static int totalStudentsCreated; static int totalStudentsHelped; int studentID; Random random = new Random(); public Student() { studentID = ++totalStudentsCreated; } int askQuestion() { totalStudentsHelped += 1; int randomNum = random.nextInt(21); //[0,1) -> [0,21) -> [5, 26) return randomNum + 5; } }
//yuec2 Yue Cheng package lab8; import java.util.*; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; public class JavaCourse implements Runnable{ List<TA> taList = new ArrayList<>(); //list of TA objects static Queue<Student> studentQ = new LinkedList<>(); // queue of Student objects static volatile boolean allDone = false; //indicator for JavaCourse to keep creating new Students int totalTAs; //used to take user input List<Thread> taThreads = new ArrayList<>(); //Contains the thread objects created for each TA int maxQLength; //stores the max Q length so far long startTime, endTime; //start and end time of this class's run() method before printReport is invoked //do not change this method public static void main(String[] args) { JavaCourse javaCourse = new JavaCourse(); Scanner input = new Scanner(System.in); System.out.println("Enter number of TAs"); javaCourse.totalTAs = input.nextInt(); for (int i = 1; i <= javaCourse.totalTAs; i++) { System.out.print("TA" + i + "\t\t"); } System.out.println("\n------------------------------------------------------------------------------"); input.close(); for (int i = 0; i < javaCourse.totalTAs; i++ ) { TA ta = new TA(); Thread t = new Thread(ta); javaCourse.taList.add(ta); javaCourse.taThreads.add(t); t.start(); } javaCourse.run(); } @Override public void run() { //write your code here startTime = System.currentTimeMillis(); while (allDone == false) { synchronized (studentQ) { Student s = new Student(); studentQ.offer(s); try { int fiveSeconds = 5; Thread.sleep(fiveSeconds); } catch (InterruptedException e) { e.printStackTrace(); } if (studentQ.size() >= maxQLength) { int size = studentQ.size(); maxQLength = size; } } // try { // int fiveSeconds = 5; // Thread.sleep(fiveSeconds); // } catch (InterruptedException e) { // e.printStackTrace(); // } // // if (studentQ.size() >= maxQLength) { // int size = studentQ.size(); // maxQLength = size; // } } for (int i = 0; i < taThreads.size(); i++) { Thread t = taThreads.get(i); try { t.join(); } catch (InterruptedException e) { e.printStackTrace(); } } endTime = System.currentTimeMillis(); printReport(); } //do not change this method void printReport() { int totalHelpTime = 0; System.out.println("-------------------------TAs---------------------------------------"); Collections.sort(taList); for (TA ta: taList) { System.out.printf("%s%2d %s %3d %s %3d %s%n", "TA", ta.taID, "helped", ta.studentsHelped, "students for", ta.helpTime, "min" ); totalHelpTime += ta.helpTime; } System.out.println("------------------------Time---------------------------------------"); System.out.printf("%-25s%5d %s%n", "Total help time: ", totalHelpTime, "min"); System.out.printf("%-25s%5d %s%n", "Max help time", totalTAs * TA.MAX_HELP_TIME, "min"); System.out.printf("%-25s%5d %s%n", "Total lapsed time: ", (endTime - startTime), "min"); System.out.println("-----------------------Students------------------------------------"); System.out.printf("%-25s%5d%n", "Total students created:", Student.totalStudentsCreated); System.out.printf("%-25s%5d%n", "Total students helped: ", Student.totalStudentsHelped); System.out.printf("%-25s%5d%n", "Max Q length: ", maxQLength); System.out.printf("%-25s%5d%n", "Students left in the Q: ", studentQ.size()); System.out.println("-------------------------------------------------------------------"); //following statements are to test console output numbers assertEquals(Student.totalStudentsCreated, studentQ.size() + Student.totalStudentsHelped); assertTrue( totalHelpTime >= totalTAs * TA.MAX_HELP_TIME); assertTrue(allDone); } }
//圖裏有橫線的變量是static的
static int taCount = 0;
//竟然不給constructor,要本身寫。不過有提示
TA() {
//注意是先加後給
taID = ++taCount;
}
//static 變量直接用就好了,不用加點
//每一個constructor裏通常是肯定ID
public Student() {
studentID = ++totalStudentsCreated;
}
//就計算每一個問題的時候加了一次
TA.totalHelpTime += questionTime;
//TA.totalHelpTime += endTime - startTime;不對啊
//已經更新過,這裏不用更新了 並且不對
//一路打印,放不進Q的緣由是變量定義不對,檢查下
【package multithreading_NumberMaker;】
//必須有try catch, why?添加的時候都要處理異常?
try {
consumer.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}