线程互斥与同步案例

来源:互联网 发布:大数据培训考试答案 编辑:程序博客网 时间:2024/06/02 05:23

一共有100个盒子,每个盒子中有一定数量的能量,每个线程持有一个盒子,向其他盒子中注入能量,实现能量守恒。

public class EnergySystem {    //能量盒子,能量存储的地方    private final double[] energyBoxes;    private final Object lockObj=new Object();    /**     * @param n 能量盒子的数量     * @param initialEnergy 每个能量盒子初始含有的能量     */    public EnergySystem(int n,double initialEnergy){        energyBoxes=new double[n];        for(int i=0;i<energyBoxes.length;i++)            energyBoxes[i]=initialEnergy;    }    /**     * 能量转移,从一个盒子到另一个盒子     */    public void transfer(int from,int to,double amount){        synchronized (lockObj){            while(energyBoxes[from]<amount)                try {                    lockObj.wait();                } catch (InterruptedException e) {                    e.printStackTrace();                }            System.out.print(Thread.currentThread().getName());            energyBoxes[from]-=amount;            System.out.printf("从%d转移%10.2f单位能量到%d",from,amount,to);            energyBoxes[to]+=amount;            System.out.printf("能量总和:%10.2f%n",getTotalEnergies());            //往其他盒子中加过能量,可能就造成某个等待的线程不需要等待            //因为不知道应该唤醒哪个线程,所以唤醒所有的线程            lockObj.notifyAll();        }    }    /**     * 获取能量世界的能量总和     */    public double getTotalEnergies(){        double sum=0;        for(double amount:energyBoxes)            sum+=amount;        return sum;    }    /**     * 返回能量盒子的长度     */    public int getBoxAmount(){        return energyBoxes.length;    }}
public class EnergyTransferTask implements Runnable{    //共享的能量世界    private EnergySystem energySystem;    //能量转移的源能量盒子下标    private int fromBox;    //单次能量转移最大单元    private double maxAmount;    //最大休眠时间    private int DELAY=10;    public EnergyTransferTask(EnergySystem energySystem,int from,double max){        this.energySystem=energySystem;        this.fromBox=from;        this.maxAmount=max;    }    @Override    public void run() {        try {            while(true){                int toBox=(int)(energySystem.getBoxAmount()* Math.random());                double amount=maxAmount*Math.random();                energySystem.transfer(fromBox,toBox,amount);                Thread.sleep((int)(DELAY*Math.random()));            }        } catch (InterruptedException e) {            e.printStackTrace();        }    }}
public class EnergySystemTest {    //将要构建的能量世界中能量盒子数量    public static final int BOX_AMOUNT=100;    //每个盒子初始能量    public static final double INITIAL_ENERGY=1000;    public static void main(String[] args){        EnergySystem eng=new EnergySystem(BOX_AMOUNT,INITIAL_ENERGY);        for(int i=0;i<BOX_AMOUNT;i++){            EnergyTransferTask task=new                    EnergyTransferTask(eng,i,INITIAL_ENERGY);            Thread t=new Thread(task,"TransferThread_"+i);            t.start();        }    }}

0 0
原创粉丝点击