1 package cn.test.muke;
2
3 public class EnergySystem {
4
5 private final double[] energyBoxes;
6 private final Object lockObj = new Object();
7
8 public EnergySystem(int n,double initEnergy) {
9 energyBoxes = new double[n];
10 for(int i = 0;i < energyBoxes.length;i++) {
11 energyBoxes[i] = initEnergy;
12 }
13 }
14
15 public void transfer(int from,int to,double amount) {
16
17 synchronized(lockObj) {
18
19 /*if(energyBoxes[from] < amount)
20 return;*/
21
22 // while循环使得当前无法转移能量的盒子进程等待,以此减小系统开销
23 // 阻止他们继续竞争cpu,置于wait set中
24 while(energyBoxes[from] < amount) {
25 try {
26 lockObj.wait();
27 } catch (InterruptedException e) {
28 e.printStackTrace();
29 }
30 }
31 System.out.print(Thread.currentThread().getName());
32 energyBoxes[from] -= amount;
33 System.out.printf("从%d转移%10.2f单位能量到%d",from,amount,to);
34 energyBoxes[to] += amount;
35 System.out.printf("能量总和:%10.2f%n", getTotalEnergies());
36
37 //唤醒所有在lockObj对象上等待的线程
38 lockObj.notifyAll();
39
40 }
41
42 }
43
44 public double getTotalEnergies() {
45 double sum = 0;
46 for(double amount:energyBoxes)
47 sum += amount;
48
49 return sum;
50 }
51
52 public int getBoxAmount() {
53 return energyBoxes.length;
54 }
55
56 }
1 package cn.test.muke;
2
3 public class EnergyTransferTask implements Runnable{
4
5 private EnergySystem energySystem;
6 private int fromBox;
7 private double maxAmount;
8 private int DELAY = 10;
9
10 public EnergyTransferTask(EnergySystem energySystem, int fromBox, double maxAmount) {
11 this.energySystem = energySystem;
12 this.fromBox = fromBox;
13 this.maxAmount = maxAmount;
14 }
15
16 public void run() {
17
18 while(true) {
19 int toBox = (int)(energySystem.getBoxAmount()*Math.random());
20 double amount = maxAmount*Math.random();
21 energySystem.transfer(fromBox,toBox,amount);
22 try {
23 Thread.sleep((int)(DELAY*Math.random()));
24 } catch (InterruptedException e) {
25 // TODO Auto-generated catch block
26 e.printStackTrace();
27 }
28 }
29
30 }
31
32 }
1 package cn.test.muke;
2
3 public class EnergySystemTest {
4
5 public static final int BOX_AMOUNT = 100;
6 public static final double INITIAL_ENERGY = 1000;
7
8 public static void main(String args[]) {
9
10 EnergySystem es = new EnergySystem(BOX_AMOUNT,INITIAL_ENERGY);
11 for(int i = 0;i < BOX_AMOUNT;i++) {
12 EnergyTransferTask ett = new EnergyTransferTask(es,i,INITIAL_ENERGY);
13 Thread t = new Thread(ett,"TransferThread_"+i);
14 t.start();
15 }
16
17 }
18
19 }