題目
猴子分桃:3只猴子搶著分100只桃子,每只搶到的猴子分去剩余桃子的一半,使用多執行緒模擬這一程序,
分析
面向物件就是抽取模型:
第一個是猴子很簡單,它有桃子數量的屬性和搶桃的行為;
第二個,表面上是桃子,但其實是一堆桃子,這里我們建模為桃籃子,它有桃子數量的屬性和減少一半的行為,
編碼
首先定義猴子,
為了方便跟蹤搶的程序我們加了一個名稱屬性,并且重寫toString方法,
在搶桃行為里我們把桃籃子傳遞進去,然后不斷地拿走一半加到自己的數量里,直到無桃可搶,為了更加現實我們在每次搶了之后等待1秒鐘,,
用多執行緒模擬,那就讓猴子繼承執行緒類,
/**
* 猴子
*/
public class Monkey extends Thread {
/** 猴子名稱 */
private String name;
/** 桃子數量 */
private int peachNum;
public Monkey(String name) {
this.name = name;
}
/**
* 搶桃
*
* @param peachBasket 桃籃子
*/
public void snatchPeach(PeachBasket peachBasket) {
for (;;) {
int half = peachBasket.reduceByHalf();
if (half == 0) {
break;
}
System.out.printf("%s搶到了%s個桃子!%n", name, half);
peachNum += half;
// 等待一秒
LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(1));
}
}
@Override
public String toString() {
return "Monkey{" +
"name='" + name + '\'' +
", peachNum=" + peachNum +
'}';
}
}
然后定義桃籃子,
構造時傳入桃子數量,
減少一半注意執行緒安全和剩余奇數的情況,
/**
* 桃籃子
*/
public class PeachBasket {
/** 桃子數量 */
private int peachNum;
public PeachBasket(int peachNum) {
this.peachNum = peachNum;
}
/**
* 減少一半
*
* @return 被分走的數量
*/
public synchronized int reduceByHalf() {
if (peachNum == 1) {
peachNum = 0;
return 1;
} else if (peachNum > 1) {
int half = peachNum / 2;
peachNum -= half;
return half;
}
return 0;
}
}
最后我們模擬這個程序
public class Test {
public static void main(String[] args) throws InterruptedException {
// 桃籃子
PeachBasket peachBasket = new PeachBasket(100);
Monkey[] monkeys = new Monkey[3];
// 只是為了等待搶完輸出結果
CountDownLatch countDownLatch = new CountDownLatch(monkeys.length);
for (int i = 0; i < monkeys.length; i++) {
// 創建猴子,設定執行緒運行時執行搶桃子的方法
monkeys[i] = new Monkey("猴子" + (i + 1)) {
@Override
public void run() {
this.snatchPeach(peachBasket);
countDownLatch.countDown();
}
};
}
// 執行緒啟動
Arrays.stream(monkeys).forEach(Thread::start);
countDownLatch.await();
// 輸出結果
Arrays.stream(monkeys).forEach(System.out::println);
}
}
運行后控制臺列印如下:
猴子1搶到了50個桃子!
猴子3搶到了12個桃子!
猴子2搶到了25個桃子!
猴子3搶到了6個桃子!
猴子1搶到了3個桃子!
猴子2搶到了2個桃子!
猴子3搶到了1個桃子!
猴子1搶到了1個桃子!
Monkey{name='猴子1', peachNum=54}
Monkey{name='猴子2', peachNum=27}
Monkey{name='猴子3', peachNum=19}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/247149.html
標籤:其他
上一篇:解決VS系列編譯器撰寫C程式遇到scanf()回傳值被忽略的問題
下一篇:基于服務器搭建部署的疫情動態地圖
