java多线程-线程交互&互斥&同步

 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 }

 

posted @ 2020-02-20 16:54  一大碗小米粥  阅读(254)  评论(0编辑  收藏  举报