package bankfrome;
import java.util.ArrayList;
import java.util.List;
/**
* 定义一个用于存储上一个客户号码的成员变量和用于存储所有等待服务的客户号码的队列集合。
* 定义一个产生新号码的方法和获取马上要为之服务的号码的方法,这两个方法被不同的线程操作了相同的数据,所以,要进行同步。
*
* @author Evan_Huang
*
*/
public class MyNumberManager {
private int serviceNumber = 1;
private List queue = new ArrayList();
/**
* 增加号码的方法,没给调用异常就集合里就增加一个号码
*/
public synchronized Integer addQueue() {
queue.add(++serviceNumber);
return serviceNumber;
}
/**
* 提供给窗口提供号码的方法
*
* @return serviceNumber
*/
public synchronized Integer getServiceNumber() {
if(!queue.isEmpty()){
return (Integer)queue.remove(0);
}else{
return null;
}
}
}
package bankfrome;
/**
* 定义三个成员变量分别指向三个MyNumberManager对象,分别表示普通、快速和VIP客户的号码管理器,
* 定义三个对应的方法来返回这三个MyNumberManager对象。 将NumberMachine类设计成单例。
*
* @author Evan_Huang
*
*/
public class MyNumberMachine {
//建立三种客户号码类型的对象
private MyNumberManager commonClient = new MyNumberManager();
private MyNumberManager quickClient = new MyNumberManager();
private MyNumberManager vipClient = new MyNumberManager();
//提供获取不同可以客户号码类型方法
public MyNumberManager getCommonClient() {
return commonClient;
}
public MyNumberManager getQuickClient() {
return quickClient;
}
public MyNumberManager getVIPClient() {
return vipClient;
}
//单例条件一:构造方法私有化
private MyNumberMachine(){}
//单例条件二内部创建私有静态对象
private static MyNumberMachine mynum = new MyNumberMachine();
//单例条件三:提供静态共有方法返回对象
public static MyNumberMachine getInstance(){
return mynum;
}
}
package bankfrome;
/**
* 三种客户类型,所以用枚举来定义
* 这里用抽象方法来覆盖toString,用内部类来返回中文名称
* @author Evan_Huang
*
*/
public enum MyClientType {
//定义三个枚举
COMMONCLIENT {
@Override
public String toStirng() {
return "普通客户";
}
},QUICKCLIENT {
@Override
public String toStirng() {
return "快速客户";
}
},VIPCLIENT {
@Override
public String toStirng() {
return "VIP客户";
}
};
//覆盖toString方法
public abstract String toStirng();
}
package bankfrome;
import java.util.Random;
import java.util.concurrent.Executors;
import java.util.logging.Logger;
public class MyServiceWindow {
private MyClientType type = MyClientType.COMMONCLIENT;
private int number = 1;
public MyClientType getType() {
return type;
}
public void setType(MyClientType type) {
this.type = type;
}
public void setNumber(int number){
this.number = number;
}
public void start(){
Executors.newSingleThreadExecutor().execute(
new Runnable(){
public void run(){
while(true){
switch(type){
case COMMONCLIENT:
commonService();
break;
case QUICKCLIENT:
quickService();
break;
case VIPCLIENT:
vipService();
break;
}
}
}
}
);
}
private void commonService(){
String windowName = " 第" + number + "号" + type + "窗口";
System.out.println(windowName + "正在获取任务!");
Integer serviceNumber = MyNumberMachine.getInstance().getCommonClient().getServiceNumber();
if(serviceNumber != null ){
System.out.println(windowName + "为第" + serviceNumber + "客户服务");
int maxRandom = MyConstants.MAX_SERVICE_TIME - MyConstants.MIN_SERVICE_TIME;
int serviceTime = new Random().nextInt(maxRandom)+1 + MyConstants.MIN_SERVICE_TIME;
try {
Thread.sleep(serviceTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(windowName + "为第" + serviceNumber + "客户服务耗时" + serviceTime/1000 + "秒");
}else{
System.out.println(windowName + "没有取得任务,休息一下");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private void quickService(){
Integer serviceNumber = MyNumberMachine.getInstance().getQuickClient().getServiceNumber();
String windowName = " 第" + number + "号" + type + "窗口";
System.out.println(windowName + "正在获取任务!");
if(serviceNumber !=null){
System.out.println(windowName + "为第" + serviceNumber + "个客户服务");
int serviceTime = MyConstants.MIN_SERVICE_TIME;
try {
Thread.sleep(serviceTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(windowName + "为第" + serviceNumber + "客户服务耗时" + serviceTime/1000 + "秒");
}else{
System.out.println(windowName + "没有取得任务");
commonService();
}
}
private void vipService(){
Integer serviceNumber = MyNumberMachine.getInstance().getVIPClient().getServiceNumber();
String windowName = " 第" + number + "号" + type + "窗口";
System.out.println(windowName + "正在获取任务!");
if(serviceNumber !=null){
System.out.println(windowName + "为第" + serviceNumber + "客户服务");
int maxRandom = MyConstants.MAX_SERVICE_TIME - MyConstants.MIN_SERVICE_TIME;
int serviceTime = new Random().nextInt(maxRandom)+1 + MyConstants.MIN_SERVICE_TIME;
try {
Thread.sleep(serviceTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(windowName + "为第" + serviceNumber + "客户服务耗时" + serviceTime/1000 + "秒");
}else{
System.out.println(windowName + "没有取得任务");
commonService();
}
}
}
package bankfrome;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.logging.Logger;
public class MyMainClass {
public static void main(String[] args) {
for(int i=1;i<5;i++){
MyServiceWindow window = new MyServiceWindow();
window.setNumber(i);
window.start();
}
MyServiceWindow expressWindow = new MyServiceWindow();
expressWindow.setType(MyClientType.QUICKCLIENT);
expressWindow.start();
MyServiceWindow vipWindow = new MyServiceWindow();
vipWindow.setType(MyClientType.VIPCLIENT);
vipWindow.start();
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
new Runnable(){
public void run(){
Integer serviceNumber = MyNumberMachine.getInstance().getCommonClient().getServiceNumber();
System.out.println("第" + serviceNumber + "号普通客户进来了再等待服务");
}
},
0,
MyConstants.COMMON_CUSTOMER_INTERVAL_TIME,
TimeUnit.SECONDS);
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
new Runnable(){
public void run(){
Integer serviceNumber = MyNumberMachine.getInstance().getQuickClient().getServiceNumber();
System.out.println("第" + serviceNumber + "号快速客户进来了再等待服务");
}
},
0,
MyConstants.COMMON_CUSTOMER_INTERVAL_TIME * 2,
TimeUnit.SECONDS);
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
new Runnable(){
public void run(){
Integer serviceNumber = MyNumberMachine.getInstance().getVIPClient().getServiceNumber();
System.out.println("第" + serviceNumber + "号VIP客户进来了再等待服务");
}
},
0,
MyConstants.COMMON_CUSTOMER_INTERVAL_TIME * 6,
TimeUnit.SECONDS);
}
}