多线程中的互斥与同步

package bxjg;

/**
 * 宇宙的能量系统
 * 遵循能量守恒定律:
 * 能量不会凭空创生或消失,只会从一处转移到另一处
 */
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;
	 }
	 
	 /**
	  * 能量的转移,从一个盒子到另一个盒子
	  * @param from 能量源
	  * @param to     能量终点 
	  * @param amount 能量值
	  */
	 public void transfer(int from, int to, double amount){
		 
		 synchronized(lockObj){
			 
//			 if (energyBoxes[from] < amount)
//				 return;
			//while循环,保证条件不满足时任务都会被条件阻挡
			 //而不是继续竞争CPU资源
			 while (energyBoxes[from] < amount){
				 try {
					//条件不满足, 将当前线程放入Wait Set
					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对象上等待的线程
			// lockObj.notifyAll();
		 }
		 
	 }
	 
	 /**
	  * 获取能量世界的能量总和 
	  */
	 public double getTotalEnergies(){
		 double sum = 0;
		 for (double amount : energyBoxes)
			 sum += amount;
		 return sum;
	 }
	 
	 /**
	  * 返回能量盒子的长度
	  */
	 public  int getBoxAmount(){
		 return energyBoxes.length;
	 }
	 
}
package bxjg;


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;
	}
	
	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();
		}
	}

}
package bxjg;


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();
    	}
    }

}

发现问题:

public class Test {
static int i;
public static void main(String[] args) {

for(i=0; i<10; i++){
   new Thread(){
       public void run(){
           System.out.println(i);
       }
   }.start();
//    try {
// Thread.sleep(100);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
}
}
}

出现结果在意料之外,结果不按顺序输出。似乎牵涉到线程与进城的关系,之后做进一步学习

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值