jaywalker
jaywalker

Reputation: 1146

Java Class with multiple methods that can be executed in a thread

I am new to Java multithreaded programming. I have a use case where I have a runnable class called Diner and based on the state of different variables in the program, I want to execute different methods of the Diner Class in parallel. One way to do that would be to have a single run() method containing multiple if conditions corresponding to different code blocks you want to execute as shown below.

    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
            }
        }
    }

However, is there a more elegant way to do this? Like rather than having a single run() method that can be parallelized, have different methods in the class that could be parallelized (overloading run() ?).

I believe I can use Akka Actors to accomplish something like this, but I am looking for a native solution.

Upvotes: 2

Views: 4114

Answers (4)

user19921349
user19921349

Reputation:

you can create two classes and call start method(basic idia) look at the example!

//class Second

public class Second extends Thread {
public void run() {
    for (int c = 100; c > 0; c--) {
        System.out.println(c);
    }
}

}

//class Main

public class Main extends Thread {
public void run() {
    for (int i = 0; i < 100; i++) {
        System.out.println(i);
    }
}


public static void main(String[] args) throws InterruptedException {
    Main thread_1 = new Main();
    Second thread_2 = new Second();

    // Let's fix concurrency problem
    // method 1:
    
    thread_1.start();
    thread_1.join();
    thread_2.start();
    thread_2.join();
    
    //method 2:
   //or you can use  is alive
   /* thread_1.start();
    while (thread_1.isAlive()){
        System.out.print("");
    }thread_2.start();*/
    

}

}

Upvotes: 0

Guido Simone
Guido Simone

Reputation: 7952

If you are new to multi-threading consider easing into it gradually. Start with a single worker thread and post all your diner's tasks to this one thread. This provides some concurrency - submitting tasks to the thread does not block - but eliminates many of the complexities of having multiple threads accessing the same Diner at the same time (synchronization, risk of deadlock, risk of race conditions etc)

Here is an example using a single thread scheduled executor. It schedules some events to happen at 2, 4 and 6 seconds, but the calling thread does not block waiting for each event (although I do add an artificial block at the end with the countdown latch, so we can shutdown the executor cleanly)

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");
    }
}

Also there is no need for your Diner to implement Runnable. Just create temporary runnables as necessary for each task.

When you need additional concurrency add a second, third executor service. If you have tasks which are "stateless" - such as a database query - you could add a new executor service with multiple threads to get better parallelism. Just make sure that when you update your diner your db threads do so by scheduling a task to the Diner executor, instead of modifying diner directly.

This would give you an Akka-esque style, but just using native Java utilities.

Upvotes: 2

Simon
Simon

Reputation: 629

In my opinion, for your case, simple inheritance can be a good option.

you can have several sub-classes inheriting Diner,

So there would be one Diner abstract class and several sub classes,

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
    }
}

// some other subclasses

in your main function, you can have

List diners = new ArrayList<Diner>();

//maybe some factory producing different diners

diners.add(fac.getDiner("not seated"));

for(Diner diner : diners){
    diner.run();
}

Upvotes: 0

bichito
bichito

Reputation: 1426

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();
        }
    }
}

EDIT

I think for your case this approach would work better. You could launch the threads in a launch task method after evaluating the boolean. Just one Diner instance

Just keep the threads in place where you can control them

Upvotes: 2

Related Questions