A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© Rancho_Gump 高级黑马   /  2013-1-3 12:02  /  1250 人查看  /  0 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

这是我自己做的一个银行排号系统,有一些问题请教下大家
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()怎么用啊?
*/

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马