这是阿里研发笔试的一道附加题,当时写的并不好,后来做了一个更好的实现方案。
题目大概要求是, 现有gift 99个, 用来回馈淘宝用户, 每个用户可以用30个积分来兑换,且每个用户只能兑换一次。 实现这个Order逻辑。
新的想法是做一个 class order, 其中包含静态变量gift 和 makeorder 方法, 当然makeorder方法一定要是同步的。
套用生产者/消费者模型, 这个order就相当于一个放馒头的筐, 此题中没有生产者, 只有消费者。
在 class Usr 中, 有一个order成员变量类型的成员变量, 表明将从这个”筐“中”吃馒头“(兑换gift)。 所以所有usr初始化时都要指向同一个order对象
Usr 实现 Runnable 接口, 在run()方法中, 实现检查是否满足 ”首次兑换“和”点券足够“ 两个条件, 满足的话则调用order 对象 or 的makeorder方法,对gift资源进行竞争。
这里要注意的一个点是, 如果竞争失败 ,如何反馈给Usr对象 ?
我的做法是, 自定义一个MyThread 类 extends Thread , 如果makeorder 发生 gift不足的情况, 则抛出这个异常。 Usr在run方法中捕捉这个异常, 如果兑换失败,则打印相关信息。
代码如下:
public class order { private static int gift =9; public synchronized void makeorder() throws MyException{ if(gift>0){ gift--; System.out.println("a gift is out "+ gift + "left"); } else{ throw new MyException(); } } public static void main(String[] args){ order or=new order(); Thread[] thread=new Thread [10]; Usr[] usr=new Usr[10]; for(int i=0;i<10;i++){ usr[i]=new Usr(or); thread[i]=new Thread(usr[i]); } for(int i=0;i<10;i++){ thread[i].start(); } try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } or.gift=9; for(int i=0;i<10;i++){ thread[i]=new Thread(usr[i]); thread[i].start(); } } } class Usr implements Runnable{ public order or =null; private boolean bought =false; public int point = 100; Usr(order or){ this.or=or; } public void run(){ if(!bought||point<30){ try{ or.makeorder(); bought=true; point-=30; } catch(MyException e ){ System.out.println(e.getMessage()); } } else{ if(bought){ System.out.println("You have buy this before!"); } else{ System.out.println("You have not enough point!"); } } System.out.println("you have "+point+"point now"); } } class MyException extends Exception{ private String message = new String("no gift left"); public String getMessage(){ return message; } }
在main方法中 ,首先创建一个order对象 or , 然后以or初始化十个 usr 对象。 建立十个线程来执行usr,在结果中可以看到,只有九个人成功购买。
然后再补充gift为9.
新建十个线程来执行Usr对象, 此时只有一个人能成功购买。
购买失败的人部件积分。
a gift is out 8left you have 70point now a gift is out 7left a gift is out 6left you have 70point now a gift is out 5left you have 70point now you have 70point now a gift is out 4left you have 70point now a gift is out 3left you have 70point now a gift is out 2left you have 70point now a gift is out 1left you have 70point now a gift is out 0left you have 70point now no gift left you have 100point now You have buy this before! you have 70point now You have buy this before! you have 70point now You have buy this before! you have 70point now You have buy this before! you have 70point now You have buy this before! You have buy this before! you have 70point now You have buy this before! you have 70point now You have buy this before! you have 70point now you have 70point now You have buy this before! you have 70point now a gift is out 8left you have 70point now
明天面试加油!
原文:http://blog.csdn.net/ltianchao/article/details/23597991