面试编程题的实验

阅读更多
昨天某知名互联网企业对我做了一个电话面试。然后叫我在他给的一个网址上面做一个编程题。
题目是这样的。



共计9个苹果,有2只猴子,一个猴子每次拿2个苹果,一个猴子每次拿3个苹果,如果剩余的苹果不够猴子每次拿的数量,则2只猴子停止拿苹果,请用java多线程模拟上面的描述




描述是挺简单的。但当在电话面试的情况下,又是一个比较知名公司的限时下。我那小心肝是紧张的,再加上是在一个非IDE环境下写代码很多API记不详细,所以导致我写出了下面的这个诡异的版本。真是丢脸呀。



//monkey2 是类似 monkey1的。当时紧张还没写完然后自己的网络突然异常了,然后就断联了。注定是抓不住机会好好表现了
private static volatile int appleStoreCount = 9;

public static void main(String... args) {
  
  ReentrantLock lock = new ReentrantLock();
	Runnable monkey1 = () -> {
      
      int takeOffNum = 2;
      
      outer : while(true){
        lock.lock()
       while( appleStoreCount >= takeOffNum) {
         
         appleStoreCount -= takeOffNum;
         lock.unlock();// 这个业务简单假设不出现异常,所以不放finally里了
         continue outer;
       }
        break;
      };
    };
   Runnable monkey2 = () -> {
     
    int takeOffNum = 3;
      while( appleStoreCount.get() > = takeOffNum){
       
         if (appleStoreCount.compareAndDecrement(takeOffNum) == false){
        	
           continue;
         }
      };
   };
  
  Thread monkey1Task = new Thread(monkey1);
  Thread monkey2Task = new Thread(monkey2);
  monkey1Task.start();
  monkey1Task.start();
     
     
     
   }




但这代码真不是我最初设想的那样的。真不知我这心里素质是什么情况了。
下面给出我冷静后并且未查询资料,只是在IDE环境下写出的代码。




private static final AtomicInteger STORE_COUNT = new AtomicInteger(9);

@Test
	public void tttt() {

		Runnable monkey1 = () -> {

			String monkeyName = "monkey1";
			int takeoffNum = 2,
					storeCountByGet = 0;
			while ((storeCountByGet = STORE_COUNT.get()) >= takeoffNum) {

				if (STORE_COUNT.compareAndSet(storeCountByGet, storeCountByGet - takeoffNum)) {

					System.out.println(monkeyName + "争抢水果成功 => " + takeoffNum);
				} else {

					System.out.println(monkeyName + "争抢水果失败");
				}
			}
		};
		Runnable monkey2 = () -> {

			String monkeyName = "monkey2";
			int takeoffNum = 3,
					storeCountByGet = 0;
			while ((storeCountByGet = STORE_COUNT.get()) >= takeoffNum) {

				if (STORE_COUNT.compareAndSet(storeCountByGet, storeCountByGet - takeoffNum)) {

					System.out.println(monkeyName + "争抢水果成功 => " + takeoffNum);
				} else {

					System.out.println(monkeyName + "争抢水果失败");
				}
			}
		};

		Thread m1Task = new Thread(monkey1);
		Thread m2Task = new Thread(monkey2);
		m2Task.start();
		m1Task.start();
	}


输出如下
monkey2争抢水果失败
monkey1争抢水果成功 => 2
monkey2争抢水果成功 => 3
monkey1争抢水果成功 => 2
monkey1争抢水果成功 => 2


这一个才是我最初设想的实现。只能说较差的心理素质和非IDE环境导致了发挥失常。可惜呀。这个实现不算完美,但算符合需求且干净的实现。


————————————————不希望被忽视的分割线——————————

这部分是我看到题目时所想到的一个扩展问题。



共计9个苹果,有2只猴子,一个猴子每次拿2个苹果,一个猴子每次拿3个苹果,如果剩余的苹果不够猴子每次拿的数量,则2只猴子停止拿苹果,两只猴子依次拿取苹果。请用java多线程模拟上面的描述



下面是我实现
private volatile Integer[] storeCount = { 9 };

	private volatile int flagInt = 2;

	@Test
	public void tttt1() {

		Runnable monkey1 = () -> {

			String monkeyName = "monkey1";
			int takeoffNum = 2,
					flagVal = 1;

			synchronized (storeCount) {

				try {
					while (storeCount[0].intValue() >= takeoffNum) {
						if (flagInt != flagVal) {

							storeCount.wait();
						}
						if (storeCount[0].intValue() >= takeoffNum) {

							storeCount[0] -= takeoffNum;
							System.out.println(monkeyName + "争抢水果成功 => " + takeoffNum);
							flagInt = 2;
							storeCount.notifyAll();
						}
					}
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}

		};
		Runnable monkey2 = () -> {

			String monkeyName = "monkey2";
			int takeoffNum = 3,
					flagVal = 2;

			synchronized (storeCount) {

				try {
					while (storeCount[0].intValue() >= takeoffNum) {
						if (flagInt != flagVal) {

							storeCount.wait();
						}
						if (storeCount[0].intValue() >= takeoffNum) {

							storeCount[0] -= takeoffNum;
							System.out.println(monkeyName + "争抢水果成功 => " + takeoffNum);
							flagInt = 1;
							storeCount.notifyAll();
						}
					}
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		};

		Thread m1Task = new Thread(monkey1);
		Thread m2Task = new Thread(monkey2);
		m1Task.start();
		m2Task.start();
	}


输出如下
monkey2争抢水果成功 => 3
monkey1争抢水果成功 => 2
monkey2争抢水果成功 => 3


将flagInt的初始值改成1后的输出如下
monkey1争抢水果成功 => 2
monkey2争抢水果成功 => 3
monkey1争抢水果成功 => 2

你可能感兴趣的:(thread,java,多线程)