---------------------- ASP.Net+Android+IOS开发、.Net培训 期待与您交流! ----------------------
听视频后的一些知识点总结:
1. if..else为什么没有switch效率高
在java中,switch会根据分支的密集程度生成不同的jvm指令。
如果分支比较密集,则生成一张跳转表,直接根据条件做跳转,反之则没有这张表,将根据case语句一条一条地比较,然后决定走那个分支。
因此,在分支较多的时候,switch的效率比if else高,而分支较少时,则差不多,但是switch的条件不如if else灵活。
2. switch除了可以接收byte,shot,int,char之外还可以接收枚举
写程序时遇到的一些问题:
1.窗口开启了,客户号也有了,服务窗口总是获取不到任务
原因:线程任务中的代码没有放到while循环中,导致线程任务代码只执行了一遍
2.获取不到号是什么原因造成的
在某个线程的run()方法中若有
while(true){System.out.prinln("aa")};这样的调试语句
则其他线程就获取不到cpu时间片,此线程会一直执行下去
故另外获取号的线程总是处于就绪状态得不到cpu的执行
时间片
3.执行start方法进入死循环了
解决:将start方法中的代码放到多线程的run方法中
让各个窗口为相应的客户服务互不干扰
/**
* 取号机
* @author Administrator
*
*/
import java.util.*;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public enum QueueMachine {
//定义客户类型
COMMON,EXPRESS,VIP;
//创建3个集合分别用于存储产生不同客户类型的号
List<Integer> commonList=new ArrayList<Integer>();
List<Integer> expressList=new ArrayList<Integer>();
List<Integer> vipList=new ArrayList<Integer>();
//客户号
private Integer customerNum=1;
@Override
public String toString() {
String type=null;
switch(this){
case COMMON:
type= "普通客户";
break;
case EXPRESS:
type= "快速客户";
break;
case VIP:
type= "VIP客户";
break;
}
return type;
}
//随机产生客户号
public synchronized void generateNewNumber(){
//根据不同的客户类型设置产生不同客户号的周期
int period=0;
switch(this){
case COMMON:
period=new Random().nextInt(3)+1;
break;
case EXPRESS:
period=new Random().nextInt(6)+1;
break;
case VIP:
period=new Random().nextInt(18)+1;
break;
}
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
new Runnable(){
public void run(){
//根据不同的客户类型将产生的号存储到不同的集合中
switch(QueueMachine.this){//指明这个this是外部类的this
case COMMON:
System.out.println(customerNum+"号普通客户,您前面有"+commonList.size()+"位客户");
commonList.add(customerNum++);
break;
case EXPRESS:
System.out.println(customerNum+"号快速客户,您前面有"+expressList.size()+"位客户");
expressList.add(customerNum++);
break;
case VIP:
System.out.println(customerNum+"号VIP客户,您前面有"+vipList.size()+"位客户");
vipList.add(customerNum++);
break;
}
}
},
0, //首次执行的延迟时间
period, //连续执行之间的周期
TimeUnit.SECONDS
);
}
//获取客户号
public synchronized Integer fetchNumber(){
//根据不同的客户类型获取不同的客户号
Integer customerNum=null;
switch(this){
case COMMON:
if(commonList.size()>0){
customerNum=commonList.remove(0);
}
break;
case EXPRESS:
if(expressList.size()>0){
customerNum=expressList.remove(0);
}
break;
case VIP:
if(vipList.size()>0){
customerNum=vipList.remove(0);
}
break;
}
return customerNum;
}
}
import java.util.Random;
import java.util.concurrent.Executors;
/**
* 普通窗口
* @author Administrator
*
*/
public class CommonWindow {
private int windowNum; //窗口号
private QueueMachine type; //服务类型
private static final int MIN_TIME=1000,MAX_TIME=10000; //设置服务的最小时间和最大时间
public CommonWindow(int windowNum,QueueMachine type) {
this.windowNum=windowNum;
this.type=type;
}
//获取普通客户号
public Integer fetchNum(){
return QueueMachine.COMMON.fetchNumber();
}
/**
* 开启窗口为客户服务
* 因为start方法会被不同的窗口所调用故要用多线程技术来实现
* 不同的窗口为不同的客户所服务,互不干扰
* 若普通窗口调用start方法,则customerNum获取的是普通客户号
* 若快速窗口调用start方法,则customerNum获取的是快速客户号,若没有获取到快速客户号则为普通客户服务
* 若VIP窗口调用start方法,则customerNum获取的是VIP客户号,若没有获取到VIP客户号则为普通客户服务
*/
public void start(){
Executors.newSingleThreadExecutor().execute(new Runnable(){
public void run(){
System.out.println(windowNum+"号["+type+"]窗口开启");
while(true){
Integer customerNum=fetchNum();
if(customerNum!=null){
System.out.println(windowNum+"号窗口为"+customerNum+"号"+type+"服务");
long cost=serviceTime();
System.out.println(windowNum+"号窗口为"+customerNum+"号"+type+"服务,耗时"+cost+"秒");
}else{
switch(type){
case EXPRESS:
case VIP:
extend();
break;
}
}
}
}
});
}
/**
* 服务时间
* 普通客户,VIP客户的服务时间是1-10s
* 快速客户的服务时间是1s
* @return
*/
private long serviceTime() {
long start=System.currentTimeMillis();
long time=MIN_TIME+(new Random().nextInt(MAX_TIME)+1);
if(type==QueueMachine.EXPRESS){
time=MIN_TIME;
}
try {
Thread.sleep(time);
} catch (InterruptedException e) {
e.printStackTrace();
}
long end=System.currentTimeMillis();
return (end-start)/1000;
}
//快速窗口,VIP窗口为普通客户服务
public void extend() {
Integer customerNum=QueueMachine.COMMON.fetchNumber();
if(customerNum!=null){
System.out.println(windowNum+"号窗口为"+customerNum+"号普通客户服务");
long cost=serviceTime();
System.out.println(windowNum+"号窗口为"+customerNum+"号普通客户服务耗费"+cost+"秒");
}
}
}
/**
* 快速窗口
* @author Administrator
*
*/
public class ExpressWindow extends CommonWindow{
public ExpressWindow(int windowNum, QueueMachine type) {
super(windowNum, type);
}
//获取快速客户号
@Override
public Integer fetchNum() {
return QueueMachine.EXPRESS.fetchNumber();
}
//快速窗口为普通客户服务
@Override
public void extend() {
super.extend();
}
}
/**
* VIP窗口
* @author Administrator
*
*/
public class VIPWindow extends CommonWindow{
public VIPWindow(int windowNum, QueueMachine type) {
super(windowNum, type);
}
//获取VIP客户号
@Override
public Integer fetchNum() {
return QueueMachine.VIP.fetchNumber();
}
//VIP窗口为普通客户服务
@Override
public void extend() {
super.extend();
}
}
/**
* 测试类
* @author Administrator
*
*/
public class MainClass {
public static void main(String[] args) {
//创建4个普通窗口并开启服务
for(int x=1; x<=4; x++){
CommonWindow cw=new CommonWindow(x, QueueMachine.COMMON);
cw.start();
}
//创建一个快速窗口并开启服务
new ExpressWindow(5, QueueMachine.EXPRESS).start();
//创建一个VIP窗口并开启服务
new VIPWindow(6, QueueMachine.VIP).start();
//产生不同类型的客户号来模拟客户办理业务
QueueMachine.COMMON.generateNewNumber();
QueueMachine.EXPRESS.generateNewNumber();
QueueMachine.VIP.generateNewNumber();
}
}
运行结果:
1号[普通客户]窗口开启
3号[普通客户]窗口开启
4号[普通客户]窗口开启
2号[普通客户]窗口开启
6号[VIP客户]窗口开启
5号[快速客户]窗口开启
1号普通客户,您前面有0位客户
6号窗口为1号普通客户服务
1号快速客户,您前面有0位客户
5号窗口为1号快速客户服务
1号VIP客户,您前面有0位客户
5号窗口为1号快速客户服务,耗时1秒
..............
---------------------- ASP.Net+Android+IOS开发、.Net培训 期待与您交流! ----------------------
详细请查看:http://edu.csdn.net