这是我自己做的一个银行排号系统,有一些问题请教下大家
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.Random;
/*
* 银行排号程序终于编写完了,多次测试中出现过这样几个问题,不知道怎么解决:
* 1,return commonList.remove(0);提示这里出现越界异常
* 2,打印中出现缺少对某个号客户的处理情况,其中一次缺少 7号xx用户
* 3,打印结果中出现了客户编号的重复:[1号普通客户][1号快速客户]
*/
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
//定时生成三种不同类型的客户
comeClient(Client.COMMON_CLIENT, 1);
comeClient(Client.RAPID_CLIENT, 3);
comeClient(Client.VIP_CLIENT, 6);
try{
Thread.sleep(5000);}catch(Exception e){}//先让程序休息5秒,聚集一些客户
//以下建立7个银行窗口,进行死循环,并让每个窗口都不停的叫号
Executors.newSingleThreadExecutor().execute(new Runnable(){
@Override
public void run() {
// TODO Auto-generated method stub
while(true)
new BankWindows().getNum();
}
});
Executors.newSingleThreadExecutor().execute(new Runnable(){
@Override
public void run() {
// TODO Auto-generated method stub
while(true)
new BankWindows("common",5).getNum();
}
});
Executors.newSingleThreadExecutor().execute(new Runnable(){
@Override
public void run() {
// TODO Auto-generated method stub
while(true)
new BankWindows("common",2).getNum();
}
});
Executors.newSingleThreadExecutor().execute(new Runnable(){
@Override
public void run() {
// TODO Auto-generated method stub
while(true)
new BankWindows("rapid",6).getNum();
}
});
Executors.newSingleThreadExecutor().execute(new Runnable(){
@Override
public void run() {
// TODO Auto-generated method stub
while(true)
new BankWindows("common",3).getNum();
}
});
Executors.newSingleThreadExecutor().execute(new Runnable(){
@Override
public void run() {
// TODO Auto-generated method stub
while(true)
new BankWindows("common",4).getNum();
}
});
Executors.newSingleThreadExecutor().execute(new Runnable(){
@Override
public void run() {
// TODO Auto-generated method stub
while(true)
new BankWindows("vip",7).getNum();
}
});
}
public static void comeClient(final Client client,int intervalTime)
{
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
new Runnable(){
@Override
public void run() {
// TODO Auto-generated method stub
new SortNum().start(client);
}
},
0,
intervalTime,
TimeUnit.SECONDS);
}
}
//这个类定义了三种不同客户原型
enum Client {
COMMON_CLIENT,RAPID_CLIENT,VIP_CLIENT;
@Override
public String toString() {
// TODO Auto-generated method stub
switch(this){
case COMMON_CLIENT:
return "普通客户";
case RAPID_CLIENT:
return "快速客户";
case VIP_CLIENT:
return "VIP客户";
}
return super.toString();
}
}
/*这个类是模拟银行排号机的系统,这个类有几个加锁的方法,多次测试中,
问题都出在同步函数处,郁闷的很啊,不知道怎么处理
*/
class SortNum {
//三个list用于记录三种客户
private static List<String> commonList = new ArrayList<String>();
private static List<String> rapidList = new ArrayList<String>();
private static List<String> vipList = new ArrayList<String>();
//对应三种客户的取出队列最前的客户的方法,用了synchronized修饰,但还会出现
//线程安全问题,这三个函数偶尔出现越界异常
public synchronized String getCommonListNum() {
if(commonList.size()>0&&commonList!=null)
return commonList.remove(0);
else
return "没有客户";
}
public synchronized String getRapidListNum() {
if(rapidList.size()>0&&rapidList!=null)
return rapidList.remove(0);
else
return "没有客户";
}
public synchronized String getVipListNum() {
if(vipList.size()>0&&vipList!=null)
return vipList.remove(0);
else
return "没有客户";
}
static int count=0;//定义计数器
/*
start()方法是记录各种客户,测试中这里出现两个第1号xx客户的情况
多线程安全问题,不知道怎么解决。
*/
public synchronized void start(Client client)
{
int n=++count;
switch(client)
{
case COMMON_CLIENT:
commonList.add("第"+n+"号普通客户");
System.out.println(commonList.toString());
break;
case RAPID_CLIENT:
rapidList.add("第"+n+"号快速客户");
System.out.println(rapidList.toString());
break;
case VIP_CLIENT:
vipList.add("第"+n+"号VIP客户");
System.out.println(vipList.toString());
break;
}
}
}
/*
这个类是模拟银行窗口的功能,它主要实现模拟办理业务功能和喊下个客户的功能
这里将两个功能合二为一,用getNum()实现
*/
class BankWindows {
private String str = "common";
private int count = 1;
public BankWindows() {
// TODO Auto-generated constructor stub
}
public BankWindows(String flag,int count)
{
this.str=flag;
this.count=count;
}
public void getNum()
{
SortNum sortNum = new SortNum();
if(str.equals("common"))
{
String client = sortNum.getCommonListNum();
while(client.equals("没有客户"))
{
System.out.println(count+"号普通窗口休息中...");
try{
Thread.sleep(1000);
}
catch(Exception e)
{
e.printStackTrace();
}
client = sortNum.getCommonListNum();
}
System.out.println(client+"正在"+count+"号普通窗口办理业务");
int m = (new Random().nextInt(9)+1)*1000;
try{
Thread.sleep(m);
}
catch(Exception e)
{
e.printStackTrace();
}
System.out.println(client+"业务办理完毕,用时"+(m/1000)+"s");
}
if(str.equals("rapid"))
{
String client = sortNum.getRapidListNum();
String client2 = sortNum.getCommonListNum();
while(client.equals("没有客户"))
{
if(client2.equals("没有客户"))
{
System.out.println(count+"号快速窗口休息中...");
try{
Thread.sleep(1000);
}
catch(Exception e)
{
e.printStackTrace();
}
//continue;
}
else
{
System.out.println(client2+"正在"+count+"号快速窗口办理业务");
int m = (new Random().nextInt(9)+1)*1000;
try{
Thread.sleep(m);
}
catch(Exception e)
{
e.printStackTrace();
}
System.out.println(client2+"业务办理完毕,用时"+(m/1000)+"s");
}
client = sortNum.getRapidListNum();
}
System.out.println(client+"正在"+count+"号快速窗口办理业务");
try{
Thread.sleep(1000);
}
catch(Exception e)
{
e.printStackTrace();
}
System.out.println(client+"业务办理完毕,用时1s");
}
if(str.equals("vip"))
{
String client = sortNum.getVipListNum();
String client2 = sortNum.getCommonListNum();
while(client.equals("没有客户"))
{
if(client2.equals("没有客户"))
{
System.out.println(count+"号VIP窗口休息中...");
try{
Thread.sleep(1000);
}
catch(Exception e)
{
e.printStackTrace();
}
//continue;
}
else
{
System.out.println(client2+"正在"+count+"号VIP窗口办理业务");
int m = (new Random().nextInt(9)+1)*1000;
try{
Thread.sleep(m);
}
catch(Exception e)
{
e.printStackTrace();
}
System.out.println(client2+"业务办理完毕,用时"+(m/1000)+"s");
}
client = sortNum.getVipListNum();
}
System.out.println(client+"正在"+count+"号VIP窗口办理业务");
int m = (new Random().nextInt(9)+1)*1000;
try{
Thread.sleep(m);
}
catch(Exception e)
{
e.printStackTrace();
}
System.out.println(client+"业务办理完毕,用时"+(m/1000)+"s");
}
}
}
/*请高人指导! 多线程的安全一般都有什么解决方案? 像我的程序的线程同步安全问题怎么解决?
还有就是 谁能给介绍下Executors类中方法的应用 比如Executors.newFixedThreadPool()怎么用啊?
*/ |
|