我是Java多线程编程的新手。我有一个用例,我有一个名为Diner
的runnable类,并且基于程序中不同变量的状态,我想并行执行Diner
类的不同方法。
一种方法是使用一个run()方法,该方法包含多个if条件,这些条件对应于您想要执行的不同代码块,如下所示。
public class Diner implements Runnable {
Order order;
int arrivalTime;
public void run () {
if(!isSeated){
//do something to get a seat
}
if(!notEatenYet){
//place order
}
if(!orderHasArrived){
//start eating
}
if(finishedEating){
//pay bill and leave
}
}
}
但是,有更优雅的方法吗?喜欢而不是使用可以并行化的单个run()
方法,在类中使用可以并行化的不同方法(重载run()
?)。
我相信我可以使用Akka Actors来完成这样的事情,但我正在寻找原生解决方案。
答案 0 :(得分:2)
如果您不熟悉多线程,请考虑逐步放宽。从单个工作线程开始,将所有用餐任务发布到这个线程。这提供了一些并发性 - 向线程提交任务不会阻止 - 但消除了让多个线程同时访问同一个Diner的许多复杂性(同步,死锁风险,竞争条件风险等)
以下是使用单线程计划执行程序的示例。它会调度某些事件发生在2,4和6秒,但是调用线程不会阻止等待每个事件(尽管我在末尾添加了一个带有倒计时锁存器的人工块,因此我们可以干净地关闭执行程序)< / p>
actual_retdate
此外,您的Diner无需实现Runnable。只是创造临时 每个任务都需要runnable。
当您需要额外的并发时,添加第二个,第三个执行器服务。如果你 有无国籍的任务&#34; - 例如数据库查询 - 您可以添加新的 具有多个线程的执行程序服务以获得更好的并行性。只要确保 当您更新您的晚餐时,您的数据库线程通过将任务安排到Diner来实现 执行者,而不是直接修改用餐者。
这将为您提供Akka-esque风格,但只使用本机Java实用程序。
答案 1 :(得分:1)
public class SOCLass {
public void method1(){
System.out.println("method1");
}
public void method2(){
System.out.println("method1");
}
public static void main(String[] args){
SOCLass clazz = new SOCLass();
Runnable task1 = () -> { clazz.method1();};
Thread t1 = new Thread(task1);
t1.start();
Runnable task2 = () -> { clazz.method2();};
Thread t2 = new Thread(task1);
t2.start();
try {
t1.join();
t2.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
编辑
我认为对于您的情况,这种方法会更好。在评估布尔值之后,您可以在启动任务方法中启动线程。只有一个Diner实例
只需将线程保持在可以控制它们的位置
答案 2 :(得分:0)
在我看来,对于你的情况,简单的继承可能是一个不错的选择。
你可以有几个继承Diner
,
所以会有一个Diner抽象类和几个子类,
public abstract class Diner implements Runable{
public Order order;
public int arrivalTime;
}
public class NotSeatedDiner extends Diner {
public void run () {
// do something to find a seat
}
}
//其他一些子类
在你的主要功能中,你可以拥有
List diners = new ArrayList<Diner>();
//maybe some factory producing different diners
diners.add(fac.getDiner("not seated"));
for(Diner diner : diners){
diner.run();
}