Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/307.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java类,具有可在一个线程中执行的多个方法_Java_Multithreading - Fatal编程技术网

Java类,具有可在一个线程中执行的多个方法

Java类,具有可在一个线程中执行的多个方法,java,multithreading,Java,Multithreading,我是Java多线程编程新手。我有一个用例,其中我有一个名为Diner的可运行类,根据程序中不同变量的状态,我希望并行执行Diner类的不同方法。 一种方法是使用一个run()方法,该方法包含多个if条件,对应于要执行的不同代码块,如下所示 public class Diner implements Runnable { Order order; int arrivalTime; public void run () {

我是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演员来完成类似的事情,但我正在寻找一个本地解决方案

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

所以会有一个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();
}
List diners=new ArrayList();
//也许是一些生产不同餐车的工厂
用餐者。添加(fac.getDiner(“未就座”);
用于(就餐者:就餐者){
进餐者跑();
}

< /代码> 如果你是新手,多线程考虑逐渐放松。从一个工作线程开始,将用餐者的所有任务都发布到这个线程。这提供了一些并发性—向线程提交任务不会阻塞—但消除了多个线程同时访问同一个Diner的许多复杂性(同步、死锁风险、竞争条件风险等)

下面是一个使用单线程调度执行器的示例。它将一些事件安排在2秒、4秒和6秒发生,但调用线程不会阻止等待每个事件(尽管我在最后添加了一个带有倒计时闩锁的人工块,因此我们可以干净地关闭执行器)

此外,您的用餐者也不需要实现Runnable。只需创建临时 根据每个任务的需要可运行

当您需要额外的并发性时,添加第二个、第三个executor服务。如果你 如果任务是“无状态的”,例如数据库查询,则可以添加新的 多线程执行器服务,以获得更好的并行性。确保 当您更新diner时,db线程通过向diner调度任务来完成更新 执行者,而不是直接修改用餐者


这将为您提供一种Akka风格,但仅使用本机Java实用程序。

您是否参考过@RajithPemabandu这篇文章?您所参考的文章只是使用
ExecutorService
启动和管理多个线程,而不是为每个线程创建一个单独的
Thread
对象。所有创建的线程只有一个需要并行执行的任务,即Ping主机。这不是我的问题所指的。你真的想并行运行这个类的方法吗?我很难想象一个用餐者同时坐下、吃饭和付账:这些动作是严格顺序的。我想说的是,系统中有多个用餐者,因此他们中的许多人可能会同时等待坐下、点菜和吃饭,因此需要多个可以“并行执行”的任务
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");
    }
}