用于模拟数据的Java多线程
因此,我目前正在创建一个数据分析和预测程序,出于测试目的,我正在模拟大量数据(范围为10000-1000000)“试验”。数据是理论游戏的模拟匹配。每场比赛都有回合。该程序的基本psudocode如下所示:用于模拟数据的Java多线程,java,multithreading,statistics,analytics,simulation,Java,Multithreading,Statistics,Analytics,Simulation,因此,我目前正在创建一个数据分析和预测程序,出于测试目的,我正在模拟大量数据(范围为10000-1000000)“试验”。数据是理论游戏的模拟匹配。每场比赛都有回合。该程序的基本psudocode如下所示: main(){ data = create(100000); saveToFile(data); } Data create(){ Data returnData = new Data(playTestMatch()); } Match playTestMatch
main(){
data = create(100000);
saveToFile(data);
}
Data create(){
Data returnData = new Data(playTestMatch());
}
Match playTestMatch(){
List<Round> rounds = new List<Round>();
while(!GameFinished){
rounds.add(playTestRound());
}
Match returnMatch = new Match(rounds);
}
Round playTestRound(){
//Do round stuff
}
main(){
数据=创建(100000);
保存文件(数据);
}
数据创建(){
数据返回数据=新数据(playTestMatch());
}
Match playTestMatch(){
列表轮数=新列表();
而(!GameFinished){
添加(playTestRound());
}
Match returnMatch=新比赛(轮);
}
Round playTestRound(){
//做圆的东西
}
现在,我想知道我是否可以在多个线程上处理这些回合的模拟,以加快进程。我不熟悉多线程背后的理论,所以请有人帮我完成这项工作,或者向我解释为什么这项工作不起作用(不会加快进程)。谢谢 如果您的代码是线程安全的,并且您可以将任务分割成彼此不依赖的离散块,那么这就相对容易了。使执行工作的类可调用,并将工作块添加到列表中,然后使用ExecutorService,如下所示:
ArrayList<Simulation> SL=new ArrayList<Simulation>();
for(int i=0; i<chunks; i++)
SL.add(new Simulation(i);
ExecutorService executor=Executors.newFixedThreadPool(nthreads);//how many threads
List<Future<Result>> results=null;
try {
results = executor.invokeAll(SL);
} catch (InterruptedException e) {
e.printStackTrace();
}
executor.shutdown();
for(Future<Result> result:results)
result.print();
ArrayList SL=new ArrayList();
对于(int i=0;i如果您的代码是线程安全的,并且您可以将任务拆分为彼此不依赖的离散块,那么这就相对容易了。使执行工作的类可调用,并将工作块添加到列表中,然后使用ExecutorService,如下所示:
ArrayList<Simulation> SL=new ArrayList<Simulation>();
for(int i=0; i<chunks; i++)
SL.add(new Simulation(i);
ExecutorService executor=Executors.newFixedThreadPool(nthreads);//how many threads
List<Future<Result>> results=null;
try {
results = executor.invokeAll(SL);
} catch (InterruptedException e) {
e.printStackTrace();
}
executor.shutdown();
for(Future<Result> result:results)
result.print();
ArrayList SL=new ArrayList();
对于(inti=0;i如果您是Java多线程新手,这个解释一开始可能有点难以理解,但我会尽量让它看起来尽可能简单
基本上,我认为,一般来说,当您拥有大型数据集时,与使用单线程方法相比,使用多线程并发运行操作确实会显著加快处理速度,但当然也有例外
你需要考虑三件事:
创建线程
管理线程
与主线程通信/共享每个线程计算的结果
创建线程:
可以通过扩展Thread类手动创建线程,也可以使用Executors类。
我更喜欢Executors类创建线程,因为它允许您创建线程池并为您执行线程管理。也就是说,它允许您重用线程池中空闲的现有线程,从而减少应用程序的内存占用。
您还必须查看ExecutorService接口,因为您将使用它来激发您的任务
管理线程:
Executors/Executors服务在自动管理线程方面做得很好,所以如果您使用它,就不必太担心线程管理
通讯:这是整个过程的关键部分。这里你必须详细考虑你的应用程序的线程安全性。
我建议使用两个队列来完成这项工作,一个用于读取数据的读取队列和一个用于写入数据的写入队列
但是,如果您使用的是简单的arraylist,请确保通过将arraylist包含在同步块中来同步代码以确保线程安全
synchronized(arrayList){
// do stuff
}如果您是Java多线程新手,这个解释一开始可能有点难以理解,但我会尽量让它看起来尽可能简单
基本上,我认为,一般来说,当您拥有大型数据集时,与使用单线程方法相比,使用多线程并发运行操作确实会显著加快处理速度,但当然也有例外
你需要考虑三件事:
创建线程
管理线程
与主线程通信/共享每个线程计算的结果
创建线程:
可以通过扩展Thread类手动创建线程,也可以使用Executors类。
我更喜欢Executors类创建线程,因为它允许您创建线程池并为您执行线程管理。也就是说,它允许您重用线程池中空闲的现有线程,从而减少应用程序的内存占用。
您还必须查看ExecutorService接口,因为您将使用它来激发您的任务
管理线程:
Executors/Executors服务在自动管理线程方面做得很好,所以如果您使用它,就不必太担心线程管理
通讯:这是整个过程的关键部分。这里你必须详细考虑你的应用程序的线程安全性。
我建议使用两个队列来完成这项工作,一个用于读取数据的读取队列和一个用于写入数据的写入队列
但是,如果您使用的是简单的arraylist,请确保通过将arraylist包含在同步块中来同步代码以确保线程安全
synchronized(arrayList){
// do stuff
}是您的代码吗?请参阅java.util.concurrent Executors和ExecutorServiceUse,以确定您的代码可以加速多少并行化。是您的代码吗?请参阅java.util.concurrent Executors和ExecutorServiceUse,以确定您的代码可以加速多少并行化。因此,基本上我是通过ear来实现的。据我所知,它不会崩溃和烧录,而且速度大大提高。如果您感兴趣,这是我的GitHub Repo链接。介意告诉我为什么它没有崩溃和烧录,尽管没有使用synchronized()块吗?@kuuy您访问“匹配”的方式arraylist并不理想,在一个中等负载的实时系统中会导致崩溃。我将简要解释为什么在您的情况下它不会崩溃。静态变量存储在Java堆的PermGen部分。PermGen默认情况下,对于客户端模式,大小非常小,32MB,对于服务器模式,大小非常小。当您运行时