Java:Threadpoolexecutor-使用作业列表提交作业?
以下代码是Java:Threadpoolexecutor-使用作业列表提交作业?,java,executorservice,threadpoolexecutor,Java,Executorservice,Threadpoolexecutor,以下代码是客户和作业经理。客户有姓名、地址和账户余额。工作是从一个客户到另一个客户的资金转移。这是一个Threadpoolexecutor培训计划。下面的版本有效,我一个接一个地提交作业 for (job jobObj : myJobOrganizer.all_jobs()) executor.submit(jobObj); customer.java public class customer { private String name; private Stri
客户
和作业经理
。客户有姓名、地址和账户余额。工作是从一个客户到另一个客户的资金转移。这是一个Threadpoolexecutor培训计划。下面的版本有效,我一个接一个地提交作业
for (job jobObj : myJobOrganizer.all_jobs())
executor.submit(jobObj);
customer.java
public class customer {
private String name;
private String adress;
private Double accountBalance;
public customer(String name, String adress, Double accountBalance)
{
this.name = name;
this.adress = adress;
this.accountBalance = accountBalance;
}
public String getName() { return name; }
public String getAdress()
{
return adress;
}
public Double getAccountBalance(){return accountBalance;}
public void setAccountBalance(double accountBalance){this.accountBalance=accountBalance;}
@Override
public String toString(){
return "[" + name+"; " +adress+"; "+accountBalance+"]";
}
}
customerOrganizer.java
import java.util.ArrayList;
import java.util.List;
public class customerOrganizer {
private static final customerOrganizer myJobOrganizer = new customerOrganizer();
public static customerOrganizer getJobOrganizer(){
return myJobOrganizer;
}
private List<customer> customerList = new ArrayList<customer>();
public void add_customer(customer kunde)
{
this.customerList.add(kunde);
}
public Iterable<customer> all_customers()
{
return this.customerList;
}
public static customerOrganizer getInstance()
{
return myJobOrganizer;
}
}
public class jobOrganizer {
private static final jobOrganizer myJobOrganizer = new jobOrganizer();
public static jobOrganizer getMyJobOrganizer() {
return myJobOrganizer;
}
private List<job> jobList = new ArrayList<job>();
public int getAmount(){ return jobList.size();}
public void add_job(job newJob) {
this.jobList.add(newJob);
}
public Iterable<job> all_jobs() {
return this.jobList;
}
public static jobOrganizer getInstance() {
return myJobOrganizer;
}
jobOrganizer.java
import java.util.ArrayList;
import java.util.List;
public class customerOrganizer {
private static final customerOrganizer myJobOrganizer = new customerOrganizer();
public static customerOrganizer getJobOrganizer(){
return myJobOrganizer;
}
private List<customer> customerList = new ArrayList<customer>();
public void add_customer(customer kunde)
{
this.customerList.add(kunde);
}
public Iterable<customer> all_customers()
{
return this.customerList;
}
public static customerOrganizer getInstance()
{
return myJobOrganizer;
}
}
public class jobOrganizer {
private static final jobOrganizer myJobOrganizer = new jobOrganizer();
public static jobOrganizer getMyJobOrganizer() {
return myJobOrganizer;
}
private List<job> jobList = new ArrayList<job>();
public int getAmount(){ return jobList.size();}
public void add_job(job newJob) {
this.jobList.add(newJob);
}
public Iterable<job> all_jobs() {
return this.jobList;
}
public static jobOrganizer getInstance() {
return myJobOrganizer;
}
所以,我有一份工作清单,我有一个想法,我应该使用它。我不想一个接一个地提交作业,而是想根据作业列表提交作业。我一开始就想到了这样的事情:
int threads = myJobOrganizer.getAmount();
ExecutorService executor = Executors.newFixedThreadPool(threads);
for (int i = 0; i <threads+1; i++){
//submit jobs? execute?
}
但我真的不知道该怎么做。基本上,我不知道如何以正确的方式从我的作业列表中提取作业,以便将它们提交给executor service>还不好,我正在处理
//连接螺纹
试一试{
睡眠(1000);
}捕捉(中断异常e){
e、 printStackTrace();
}
//控制打印
System.out.println(myCustomerOrganizer.all_customers().toString());
请注意,此编辑是为了完成条目,但仍然是错误的(遗憾的)。提供的答案与原始问题相关,与螺纹安全无关
谢谢你的时间和努力
ExecutorService
处理任务在工作人员之间的分配方式。你所要做的就是一个接一个地通过考试
for (job jobObj : myJobOrganizer.all_jobs())
executor.submit(jobObj);
请注意,sumbit
返回一个Future
,用于跟踪任务是否完成,或者任务是否出错(以及任务结果,但runnable没有结果)。如果您关心这些东西,您可能希望将它们收集到某种容器中,如列表
如果将
作业
更改为可调用的
,则提交将更容易Callable
是Runnable的某种扩展,允许任务在完成时生成结果。因为您的传输没有结果,所以使用java.lang.Void
作为泛型参数的填充类型就可以了
现在,只需执行executor.invokeAll(myJobOrganizer.all_jobs())就足够了。这将节省一些上下文切换,加快一些速度。(实际上非常重要,因为你的任务都很小)
顺便说一句,您应该知道并发访问需要适当的同步,而您没有同步。如果不同的工作涉及同一个帐户,您的帐户可能会以错误的状态结束。我们还通常在LargeCamelCase中命名类,在smallCamelCase中命名方法。如果您不想使用循环,可以使用
流来实现这一点。如果您使用的java版本大于或等于8,这里是一个示例
myJobList
.stream()
.forEach(e -> executor.execute(() -> {
//submit the jobs
}));
或
如果您真的不想循环,可以使用executor.invokeAll(myJobList)
提交列表
无论我发现这个答案有多有趣,你都应该仔细研究它请坚持Java命名约定!类总是在
PascalCase
-我会说“没有例外”;但是Exception
也在PascalCase
中camelCase
为字段和变量保留。在公共论坛(如SO)上发布时,请特别注意这一点,因为我们发现不一致的代码很难阅读。请注意,此代码非常不正确-没有可见性或线程安全考虑,运行此代码的任何输出都可能是随机错误的。事实上,JMM甚至不能保证编写double
是原子的!此外,您还丢弃了从submit()
返回的Future
,从而忽略了在执行代码时可能发生的任何错误。谢谢您的提醒。我试着一步一步地做每件事,但忘记了,其他读者不会自然地想到线程安全性等。我读了一些关于它的文章,稍后我会发布一个编辑,当我处理它时(如果我设法^^^^)你的“线程安全性”“编辑-它对线程安全没有任何作用,您的建议使访问器同步将修复可见性而不是正确性。注意,不断更新你的问题以提出完全不同的问题被认为是不礼貌的——人们花时间阅读问题并提供答案;您的编辑使答案不完整/不正确。@BoristheSpider我不想问更多的问题(我知道,事实上我问过),我只是想完成条目,正如前面提到的,这个程序不是线程安全的。不,他使用runnable而不是callable,这不是invokeAll的有效参数。使用流
逐个提交仍然是逐个提交。如果您删除了答案的第一部分,并对第二部分进行了大量扩展(阻塞行为、检测故障等),则此答案是可以接受的。编辑了我的答案,然后:p对于我的答案还是。。?
myJobList
.stream()
.forEach(e -> executor.execute(() -> {
//submit the jobs
}));
myJobOrganizer.all_jobs()
.stream()
.forEach(e -> executor.submit(e));