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 }