我是 Java 多线程编程新手。我有一个用例,我有一个名为 Diner
的可运行类,并且根据程序中不同变量的状态,我想执行 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 来完成这样的事情,但我正在寻找一个 native 解决方案。
最佳答案
如果您不熟悉多线程,请考虑逐渐熟悉它。从单个工作线程开始,并将所有就餐者的任务发布到该线程。这提供了一些并发性 - 向线程提交任务不会阻塞 - 但消除了多个线程同时访问同一个 Diner 的许多复杂性(同步、死锁风险、竞争条件风险等)
这是一个使用单线程调度执行器的示例。它安排一些事件在 2、4 和 6 秒发生,但调用线程不会阻塞等待每个事件(尽管我确实在最后使用倒计时锁存器添加了一个人工阻塞,因此我们可以干净地关闭执行器)
public class Diner {
public void findSeat() {
System.out.println("findSeat");
}
public void placeOrder() {
System.out.println("placeOrder");
}
public static void main(String[] args) throws InterruptedException {
final ScheduledExecutorService exec = Executors.newSingleThreadScheduledExecutor();
final CountDownLatch done = new CountDownLatch(1);
final Diner diner = new Diner();
exec.schedule(new Runnable() {
public void run() {
diner.findSeat();
}
}, 2, TimeUnit.SECONDS);
exec.schedule(new Runnable() {
public void run() {
diner.placeOrder();
}
}, 4, TimeUnit.SECONDS);
exec.schedule(new Runnable() {
public void run() {
done.countDown();
}
}, 6, TimeUnit.SECONDS);
done.await();
exec.shutdown();
System.out.println("done");
}
}
此外,您的 Diner 不需要实现 Runnable。只需创建临时的 每个任务所需的可运行程序。
当您需要额外的并发性时,请添加第二个、第三个执行程序服务。如果你 有“无状态”的任务 - 例如数据库查询 - 您可以添加新的 执行器服务具有多个线程以获得更好的并行性。只要确保 当您更新您的小餐馆时,您的数据库线程通过向小餐馆安排任务来完成此操作 executor,而不是直接修改diner。
这将为您提供 Akka 风格的风格,但仅使用 native Java 实用程序。
关于具有多个可以在线程中执行的方法的 Java 类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43151416/