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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 党巾水 中级黑马   /  2012-7-23 09:55  /  3590 人查看  /  4 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 刘馨琪 于 2012-8-14 16:17 编辑



我在做银行系统的时候出现图中标蓝的情况,我希望这里应该出现获取任务后来了客户应该就可以取到任务,我觉得可能是线程同步的问题,可又不知道怎么改,请问怎么办?谢谢
下面贴出部分代码,我认为可能需要做分析的部分。


代码如下:
主程序:
  1. import java.util.concurrent.Executors;
  2. import java.util.concurrent.TimeUnit;

  3. public class MainClass {
  4.         public static void main(String[] args){
  5.                 for (int i = 1; i < 5; i++) {
  6.                         ServiceWindow commonWindow = new ServiceWindow();
  7.                         commonWindow.setWindowID(i);
  8.                         commonWindow.start();
  9.                 }
  10.                
  11.                 ServiceWindow expressWindow = new ServiceWindow();
  12.                 expressWindow.setType(CustomerType.EXPRESS);
  13.                 expressWindow.setWindowID(1);
  14.                 expressWindow.start();
  15.                
  16.                 ServiceWindow vipWindow = new ServiceWindow();
  17.                 vipWindow.setType(CustomerType.VIP);
  18.                 vipWindow.setWindowID(1);
  19.                 vipWindow.start();
  20.                
  21.                 Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
  22.                                 new Runnable(){
  23.                                         public void run() {
  24.                                                 Integer number = NumberMachine.getInsance().getCommonManger().generateNewNumber();
  25.                                                 System.out.println(number + "号普通客户在等待服务");
  26.                                         }
  27.                                        
  28.                                 },
  29.                                 0,
  30.                                 Constants.COMMON_CUSTOMER_INTERVAL_TIME,
  31.                                 TimeUnit.SECONDS);
  32.                
  33.                 Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
  34.                                 new Runnable(){
  35.                                         public void run() {
  36.                                                 Integer number = NumberMachine.getInsance().getExpressManger().generateNewNumber();
  37.                                                 System.out.println(number + "号快速客户在等待服务");
  38.                                         }
  39.                                        
  40.                                 },
  41.                                 0,
  42.                                 Constants.EXPRESS_CUSTOMER_INTERVAL_TIME,
  43.                                 TimeUnit.SECONDS);
  44.                
  45.                 Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
  46.                                 new Runnable(){
  47.                                         public void run() {
  48.                                                 Integer number = NumberMachine.getInsance().getVipManger().generateNewNumber();
  49.                                                 System.out.println(number + "号VIP客户在等待服务");        
  50.                                         }
  51.                                        
  52.                                 },
  53.                                 0,
  54.                                 Constants.VIP_CUSTOMER_INTERVAL_TIME,
  55.                                 TimeUnit.SECONDS);
  56.         }
  57. }
复制代码

复制代码
下面这段是叫号机管理系统:
  1. import java.util.ArrayList;
  2. import java.util.List;

  3. public class NumberManger {
  4.         private int lastNumber = 1;
  5.         private List<Integer> queueNumber = new ArrayList<Integer>();
  6.         
  7.         public synchronized Integer generateNewNumber(){
  8.                 queueNumber.add(lastNumber);
  9.                 return lastNumber++;
  10.         }
  11.         
  12.         public synchronized Integer fetchServiceNumber(){
  13.                 Integer number = null;
  14.                 if(queueNumber.size() > 0){
  15.                         number = queueNumber.remove(0);
  16.                 }
  17.                 return number;
  18.         }
  19. }
复制代码

评分

参与人数 1技术分 +1 收起 理由
蒋映辉 + 1

查看全部评分

4 个回复

倒序浏览
党巾水 来自手机 中级黑马 2012-7-26 13:38:29
沙发
没有人解答乎?
来自:黑马程序员训练营论坛 Android客户端来自: Android客户端
回复 使用道具 举报
成了死贴?
回复 使用道具 举报
本帖最后由 王渠 于 2012-7-27 17:28 编辑
  1. import java.util.ArrayList;
  2. import java.util.List;

  3. public class NumberManger {
  4.         private int lastNumber = 1;
  5.         private List<Integer> queueNumber = new ArrayList<Integer>();
  6.         
  7.         public synchronized Integer generateNewNumber(){
  8.                 queueNumber.add(lastNumber);
  9.                 return lastNumber++;
  10.         }
  11.         
  12.         public synchronized Integer fetchServiceNumber(){
  13.                 Integer number = null;
  14.                 if(queueNumber.size() > 0){
  15.                         number = queueNumber.remove(0);
  16.                 }
  17.                 return number;
  18.         }
  19. }
复制代码
上面是产生用户,和消亡用户的两个同步的方法。保证了多线程时,不会出现安全问题。
import java.util.Random;
import java.util.concurrent.Executors;

public class ServiceWindow {
        public void setType(CustomerType type) {
                this.type = type;
        }

        public void setWindowID(int windowID) {
                this.windowID = windowID;
        }

        private CustomerType type = CustomerType.COMMON;
        private int windowID = 1;
        
        public void start(){
                Executors.newSingleThreadExecutor().execute(new Runnable(){
                        public void run(){
                                while (true) {
switch (type) {
                                        case COMMON:
                                                commonService();
                                                break;
                                        case EXPRESS:
                                                expressService();
                                                break;
                                        case VIP:
                                                vipService();
                                                break;
                                        }
                                }
                        }
                });               
        }
private void commonService() {
                String windowName ="第" + windowID + "号" + type + "窗口";                                                
                Integer number = NumberMachine.getInsance().getCommonManger().fetchServiceNumber();//这里用到了同步的方法,无论值是否为null,都会输出下面的话。线程对应窗口输出了下面的话。
                System.out.println(windowName + "正在获取任务");               
               
                if (number != null) {//此时第一个用户还没有进来,判断为false。
                        System.out.println(windowName + "为第" + number +"个" + "普通客户服务中………………!");
                        long beginTime = System.currentTimeMillis();
                        int maxRand = Constants.Max_Service_Time - Constants.Min_Service_Time;
                        long serveTime = new Random().nextInt(maxRand + 1) + Constants.Min_Service_Time;
                        try {
                                Thread.sleep(serveTime);
                        } catch (InterruptedException e) {
                                e.printStackTrace();
                        }
                        long costTime = System.currentTimeMillis()-beginTime;
                        System.out.println(windowName + "为第" + number +"个" + "普通客户完成服务,耗时" + costTime/1000 + "秒");
                } else {
                        System.out.println(windowName + "没有取到任务,正在休息1秒……");//判断到用户数量为0了,正准备打印这句话,挂上了。进入阻塞了。同时,1号用户产生了,并打印了1号用户在等待的话,该线程才获取到cpu执行权,开始被执行,打印了这句话。出现了蓝色部分的情况,是正常的现象。
                        
try {
                                Thread.sleep(1000);
                        } catch (InterruptedException e) {
                                e.printStackTrace();
                        }
                }
        }
        
        private void expressService() {
                String windowName ="第" + windowID + "号" + type + "窗口";                                                                                       
                Integer number = NumberMachine.getInsance().getExpressManger().fetchServiceNumber();
                System.out.println(windowName + "正在获取任务");        
               
                if (number != null) {
                        System.out.println(windowName + "为第" + number +"个" +type + "客户服务中………………!");
                        long beginTime = System.currentTimeMillis();
                        //int maxRand = Constants.Max_Service_Time - Constants.Min_Service_Time;
                        //long serveTime = new Random().nextInt(maxRand) + 1 + Constants.Min_Service_Time;
                        try {
                                Thread.sleep(Constants.Min_Service_Time);
                        } catch (InterruptedException e) {
                                e.printStackTrace();
                        }
                        long costTime = System.currentTimeMillis()-beginTime;
                        System.out.println(windowName + "为第" + number +"个" +type + "客户完成服务,耗时" + costTime/1000 + "秒");
                } else {
                        System.out.println(windowName + "没有取到任务");
                        commonService();
                }
        }
        
        private void vipService() {
                String windowName ="第" + windowID + "号" + type + "窗口";                                                                                
                Integer number = NumberMachine.getInsance().getVipManger().fetchServiceNumber();
                System.out.println(windowName + "正在获取任务");               
               
                if (number != null) {
                        System.out.println(windowName + "为第" + number +"个" +type + "客户服务中………………!");
                        long beginTime = System.currentTimeMillis();
                        int maxRand = Constants.Max_Service_Time - Constants.Min_Service_Time;
                        long serveTime = new Random().nextInt(maxRand + 1) + Constants.Min_Service_Time;
                        try {
                                Thread.sleep(serveTime);
                        } catch (InterruptedException e) {
                                e.printStackTrace();
                        }
                        long costTime = System.currentTimeMillis()-beginTime;
                        System.out.println(windowName + "为第" + number +"个" +type + "客户完成服务,耗时" + costTime/1000 + "秒");
                } else {
                        System.out.println(windowName + "没有取到任务");
                        commonService();
                }
        }
}
回复 使用道具 举报
王渠 发表于 2012-7-27 17:08
上面是产生用户,和消亡用户的两个同步的方法。保证了多线程时,不会出现安全问题。
import java.util.Rand ...

谢谢啦!我好好看一下
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马