首页 > 其他分享 >线程互斥与同步案例

线程互斥与同步案例

时间:2022-12-12 16:31:32浏览次数:43  
标签:energyBoxes 盒子 案例 int double 互斥 线程 能量 public


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



标签:energyBoxes,盒子,案例,int,double,互斥,线程,能量,public
From: https://blog.51cto.com/u_12026373/5930817

相关文章

  • <二>线程间互斥-mutex互斥锁和lock_guard
    多线程程序竞态条件:多线程程序执行的结果是一致的,不会随着CPU对线程不同的调用顺序而产生不同的运行结果.解决?:互斥锁mutex经典的卖票问题,三个线程卖100张票代码1......
  • IIS 之 连接数、并发连接数、最大并发工作线程数、队列长度、最大工作进程数
    http://t.zoukankan.com/l1pe1-p-7742936.html一、IIS连接数一般购买过虚拟主机的朋友都熟悉购买时,会限制IIS连接数,顾名思义即为IIS服务器可以同时容纳客户请求的最......
  • 线程池
    importjava.util.concurrent.ArrayBlockingQueue;importjava.util.concurrent.Executors;importjava.util.concurrent.ThreadPoolExecutor;importjava.util.concur......
  • <一>通过thread类编写C++多线程程序
    C++语言层面多线程=>好处:跨平台windows/linuxthread/mutex/condition_variablelock_gurad/unique_lockatomic/原子类型,基于CAS操作的原子类型线程安全的睡眠sleep_f......
  • 【服务器数据恢复】VMware虚拟化重装系统导致服务器崩溃的数据恢复案例
    服务器数据恢复环境:VMware虚拟化平台;vmfs文件系统。服务器故障&分析:误操作将虚拟化重装系统,服务器崩溃。正常情况下,重装系统会导致文件系统元文件很高的概率被覆盖。恢......
  • python爬虫单线程与多线程区别
    之前有人请我帮忙写一个有关招聘的爬虫,一开始先是单线程,结果显而易见非常慢,后来改了多线程,速度杠杠的。1、单线程importurllibimporturllib.requestimportrequestsimport......
  • 集合之斗地主案例
    1packagecom.Lucky.AppUnit;23/**4*开启App入口5*/6publicclassApp{7publicstaticvoidmain(String[]args){8//newstart......
  • C++爬虫如何进行多线程调试
    我们知道在爬虫钱进行多线程调试是非常重要的,之前我们也有讨论过程序调试,今天我们还将继续在这里深入的讲解下软件调试的一些内容。比如说常见的条件断点,数据断点,多线程断点......
  • 多线程爬虫如何实现线程安全?
    做大数据抓取的应当都知道,多线程爬取数据能够有效的提供工作效率、降低运营成本。那么在编程爬虫代码的时候如果保证线程安全呢?下面我们就来聊一聊。1、什么是线程安全问题......
  • 为什么 Random.Shared 是线程安全的
    在多线程环境中使用Random类来生成伪随机数时,很容易出现线程安全问题。例如,当多个线程同时调用Next方法时,可能会出现种子被意外修改的情况,导致生成的伪随机数不符合预......