Understanding the Executor Framework

Asked 1 years ago, Updated 1 years ago, 36 views

Instead of inheriting the Thread class or implementing the Runnable interface, I would like to implement a shared object class with the following methods, using the Executor framework so that the set() and reset() methods are called and output alternately.

However, maybe the code is written badly (probably) and it's deadlocked, so it doesn't work.With the newFixedThreadPool(2) method, is it possible for each of the two threads to control the order of execution?

If there is a problem with the class design, you can change the way you create the class.

class Share{
     private int a = 0;
     private String b;

     public synchronized void set() {
          while(a!=0){
              try{
                   wait();
              } catch(InterruptedExceptione) {
                 e.printStackTrace();
              }
              notify();
              a++;
              b = "data";
              System.out.println("set()a:"+a+"b:"+b);
          }
     }
     public synchronized void reset() {
          while(b==null){
              try{
                   wait();
              } catch(InterruptedExceptione) {
                 e.printStackTrace();
              }
              notify();
              a--;
              b = null;
              System.out.println("reset()a:"+a+"b:"+b);
          }
     }
}

*The following two subclasses that inherit the Thread class are defined in the run() method to call the set() and reset() methods respectively, and if you call start() in main, it will work, but I asked you a question that Executor wanted to learn from simple operations.

I am sorry that the class, field, and class block are popping out for some reason.

*Additional information

public static void main(String[]args){

     ExecutorService service = null;

     try{
         service=Executors.newFixedThreadPool(2);

         Runnable task1=()->{
              for(inti=0;i<5;i++){
                   newShare().set();
              }
         };

         Runnable task2=()->{
              for(inti=0;i<5;i++){
                   newShare().reset();
              }
         };
         
         service.execute(task1);
         service.execute(task2);

         service.shutdown();
     }
}

java

2022-09-30 21:39

1 Answers

What do you want to do is like this?

import java.util.current.ExecutorService;
import java.util.current.Executors;

public class App {

    public static void main(final String[]args) {
        final Share share=new Share();

        final Runnable setter = new Runnable() {
            @ Override
            public void run() {
                share.set();
            }
        };
        final Runnable resetter = new Runnable() {
            @ Override
            public void run() {
                share.reset();
            }
        };

        finalExecutorServices=Executors.newFixedThreadPool(2);
        // Note: Strictly speaking, there is no guarantee that the set method will be called before reset.
        es.execute(setter);
        es.execute(resetter);

    }
}

classShare{
    private int a = 0;
    private String b;

    public synchronized void set() {
        System.out.println("called set");
        do{
            a++;
            b = "data";
            System.out.println("set()a:"+a+"b:"+b);

            notify();

            try{
                wait();
                System.out.println("setter waked");
            } catch(final InterruptedExceptione){
                e.printStackTrace();
            }
        } while(a==0);
    }

    public synchronized void reset() {
        System.out.println("called reset");
        do{
            a--;
            b = null;
            System.out.println("reset()a:"+a+"b:"+b);

            notify();

            try{
                wait();
                System.out.println("resetter waked");
            } catch(final InterruptedExceptione){
                e.printStackTrace();
            }
        } while(b!=null);
    }
}

(Probably) deadlocked and it doesn't work.

As for the code that is written, it is not deadlocked (depending on how it is executed) and the set method is a==0, so it returns immediately without entering the while loop, and the reset method is waiting indefinitely in the first wait().

In the main method added, newShare() is done for each call, so the set and reset are simply operating in parallel without any coordination.
What kind of behavior do you expect to see?


2022-09-30 21:39

If you have any answers or tips


© 2024 OneMinuteCode. All rights reserved.