------- android培训、java培训、期待与您交流! ----------
银行业务调度系统初次接触感到比较复杂,为了便于理解就按照张老师的思路写了一个只有普通窗口的简化版的银行调度系统,其实思想和方法都是一样的,就是少了一个枚举类和根据获得的枚举类使ServiceWindow类进行不同操作的过程,这相当于是一个只有一个元素的枚举。
import java.util.ArrayList;
import java.util.List;
/*具有产生票和消除票两种方法,票数是这两种方法的共享数据,又由于票的增加和减少在现实中是
* 同时进行的(在银行有人在办理业务的同时又有人取票),也就是是说这一数据是被两个线程操作的
* 所以对于共享数据--票数要加锁
*/
public class NumberManager {
private int num = 0;
//取票的人是需要排队的,所以要定义一个容器
List queueNum = new ArrayList();
//使用同步函数,同时需要知道是哪个客户再取票所以返回票号
public synchronized Integer addNum()
{
queueNum.add(++num);
return num;
}
//模拟用户接受服务后票数要减少一张,同时需要知道是哪个客户接受服务所以返回票号
public synchronized Integer fetchNum()
{
if(queueNum.size() > 0)
{
return (Integer)queueNum.remove(0);
}
else {
return null;
}
}
}
<p>// 取票机只有一台,设计成单例子模式
public class NumberMachine {</p><p> private NumberMachine(){}
private static NumberMachine numberMachine = new NumberMachine();
public static NumberMachine getInstance()
{
return numberMachine;
}
private static NumberManager commonManager = new NumberManager();
//其实可以设计一个更简单的commonManager单例类,用于使用NumberManager获取票的方法
public static NumberManager getCommonManager()
{
return commonManager;
}
}
</p><p>import java.util.Random;
import java.util.concurrent.Executors;</p><p>import org.omg.CORBA.PRIVATE_MEMBER;</p><p>/*
* 银行服务窗口这个类的作用是产生一个窗口,而且具有隔段时间叫号一次,如果有客户就为他服务,
* 服务过程用sleep模拟,服务完成后就消除这个号的方法。
*
*/
public class ServiceWindow {
//产生的窗口名称标记
private int windowNum;
public ServiceWindow(int windowNum)
{
this.windowNum = windowNum;
}</p><p> //窗口叫号,就是创建一个减少票的线程
public void start()
{
Executors.newSingleThreadExecutor().execute(
new Runnable() {
@Override
public void run() {
while(true)
{
commonService();
}
}
});
}
//具体叫号方法
void commonService()
{
//先查看有没有票,获得一张票号
System.out.println("第"+windowNum+"号普通窗口开始叫号");
Integer currentNum = NumberMachine.getInstance().getCommonManager().fetchNum();
if(currentNum != null)
{
System.out.println("第"+windowNum+"号普通窗口开始为"+currentNum+"号用户服务");
//服务时间在1~10S之间
int serviceTime = new Random().nextInt(10)+1;
try {
Thread.sleep(serviceTime*1000);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("第"+windowNum+"号普通窗口开始为"+currentNum+"号用户服务 时间为"+serviceTime+"s");
}
else {
System.out.println("第"+windowNum+"号普通窗口没有取到普通任务,正在空闲一秒");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
</p><p>import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;</p><p>
public class MainClass {</p><p> public static void main(String[] args) {
//创建4个窗口
for(int i = 0; i < 5; i++)
{
ServiceWindow serviceWindow = new ServiceWindow(i);
serviceWindow.start();
}
//每个10秒有1个客户开始取票
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
new Runnable() {
@Override
public void run() {
Integer serviceNumber = NumberMachine.getInstance().getCommonManager().addNum();
System.out.println("第"+serviceNumber+"号客户正在等待服务");
}
},
0,
1,
TimeUnit.SECONDS);
}</p><p>}
</p><p></p>
部分运行结果:
第4号普通窗口开始叫号
第4号普通窗口开始为8号用户服务
第9号客户正在等待服务
第4号普通窗口开始为8号用户服务 时间为1s
第4号普通窗口开始叫号
第4号普通窗口开始为9号用户服务
第10号客户正在等待服务
第11号客户正在等待服务
第2号普通窗口开始为4号用户服务 时间为7s
第2号普通窗口开始叫号
第2号普通窗口开始为10号用户服务
第12号客户正在等待服务
第13号客户正在等待服务
第3号普通窗口开始为5号用户服务 时间为8s
第3号普通窗口开始叫号
第3号普通窗口开始为11号用户服务
第14号客户正在等待服务
第15号客户正在等待服务
第2号普通窗口开始为10号用户服务 时间为4s
第2号普通窗口开始叫号
第2号普通窗口开始为12号用户服务
如有疑问的同学,请参看:http://heimacxy.blog.163.com/blog/static/1903840442011611112028947/ 或 http://www.cnblogs.com/hm-chentao