以下のようなメソッドを持った共有オブジェクトクラスを、Threadクラスを継承する方法やRunnableインターフェイスを実装する方法ではなく、Executorフレームワークを使って利用し、set()メソッドとreset()メソッドが交互に呼び出され出力するように実装してみたいです。しかし、コードの書き方が悪いのか(おそらく)デッドロック状態になってしまい、うまくいきません。newFixedThreadPool(2)メソッドで、2つのメソッドを2つのスレッドがそれぞれ担当し、実行順序まで制御することは可能でしょうか?もしクラス設計に問題がある場合は、クラスの作り方を変えても構いません。

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

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

※以下、Threadクラスを継承したサブクラスを2つ作り、run()メソッドの中でそれぞれset()、reset()メソッドを呼び出すよう定義し、mainでstart()を呼び出すとうまくいきますが、Executorで単純な動作から学びたく質問させて頂きました。

何故かクラスとフィールド、クラスブロックが飛び出していてすいません。

※追記

public static void main(String[] args) {

     ExecutorService service = null;

     try {
         service = Executors.newFixedThreadPool(2);

         Runnable task1 = () -> {
              for(int i = 0; i < 5; i++) {
                   new Share().set();
              }
         };

         Runnable task2 = () -> {
              for(int i = 0; i < 5; i++) {
                   new Share().reset();
              }
         };

         service.execute(task1);
         service.execute(task2);

         service.shutdown();
     }
}