multithreading coding

分类:公共资源问题、公交车问题

顺序:Qseater lab, bank, doctor

【饭店】

 geust

//yuec2 Yue Cheng
package lab9;

public abstract class Guest {

    int mealOrder;
    abstract void placeOrder();

}
View Code

Group

//yuec2 Yue Cheng
package lab9;

public class Group extends Guest {

    static int groupsServed;
    int mealOrder = 4;

    @Override
    void placeOrder() {
        groupsServed++;
    }

}
View Code

Individual

//yuec2 Yue Cheng
package lab9;

public class Individual extends Guest {
    //只多不少,变量也可以继承
    static int individualsServed;
    int mealOrder = 1;

    @Override
    void placeOrder() {
        individualsServed++;
    }

}
View Code

DynamicDiner

//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);
    }
}
View Code

DynamicKitchen

//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;
                }
            }

        }
    }
}
View Code

//注释一下哦

int type = rand.nextInt(2); // [0,1) -> [0,2) -> [0,1]

 

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();
            }
        }
    }    
}
View Code

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();
            }
        }

    }

}
View Code

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;
    }
}
View Code

//要更新的变量,这里设置成啥?完成后再改,没有变量就不需要设置

// this.endTime = endTime;

 

 

【Qseater

package multithreading_Qseater;

public class Person {
    int id;
    //被static修饰的成员变量和成员方法独立于该类的任何对象。也就是说,它不依赖类特定的实例,被类的所有实例共享。
    static int count;
//好像都这样
    Person() {
        id = count++;
    }
}
View Code
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 
}
View Code
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
View Code

 【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 + "		");
        }
        System.out.println("
------------------------------------------------------------------------------");
        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);
    }
}
View Code
//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("		");
        }
        return spaces.toString();
    }
}
View Code
//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; 
    }
}
View Code
//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 + "		");
        }
        System.out.println("
------------------------------------------------------------------------------");
        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);
    }
}
View Code

//图里有横线的变量是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();

}

原文地址:https://www.cnblogs.com/immiao0319/p/10048899.html