title: How do javafx multithreading execute sequentially?
body: <p>I don't know if there are any other good ways to achieve the results I want, thank you.</p>
  
  <p>I have a requirement, according to the URL, create multiple webview threads, and execute them in order, such as thread execution, then trigger thread two execution, and so on, I use the synchronized (lobject) method, but in JAVAfx encountered a problem, the code is as follows:</p>
  
  <pre><code>public class LockObject {
  
      public int orderNum = 1;
      public final static int MaxValue=9;
  
      public LockObject(int orderNum){
          this.orderNum = orderNum;
      }
  }
  </code></pre>
  
  <p><br/></p>
  
  <pre><code>public class DownloadThread extends Thread{
  
      private LockObject lobject;
      private int printNum =0;
      private String url;
  
      public DownloadThread(LockObject lobject,int printNum,String url){
          this.lobject=lobject;
          this.printNum = printNum;
          this.url = url;
      }
      @Override
      public void run() {
          synchronized(lobject){
              while(lobject.orderNum &lt;= lobject.MaxValue){
                  if(lobject.orderNum == printNum){
                      System.out.print(printNum);
                      Platform.runLater(new Runnable() {
                          @Override
                          public void run() {
                              webView.getEngine().load(url);
                              webView.getEngine().getLoadWorker().stateProperty().addListener(new ChangeListener&lt;Worker.State&gt;() {
                                  @Override
                                  public void changed(ObservableValue&lt;? extends Worker.State&gt; observable, Worker.State oldValue, Worker.State newValue) {
                                      if (newValue == Worker.State.SUCCEEDED) {
                                          try {
                                              //xxxxx 
  
                                              // java.lang.IllegalMonitorStateException
                                              lobject.notifyAll();
                                          } catch (Exception e) {
                                              e.printStackTrace();
                                          }
                                      }
                                  }
                              });
                          }
                      });
                      lobject.orderNum++;
                      if(lobject.orderNum==downloadThreads.length){
                          saveCsvFile(goodCSVS);
                      }
                      //lobject.notifyAll();  is ok
                  }else{
                      try {
                          lobject.wait();
                      } catch (InterruptedException e) {
                          e.printStackTrace();
                      }
                  }
              }
          }
      }
  }
  </code></pre>
  
  <p><br/></p>
  
  <p>Place of call</p>
  
  <p><br/></p>
  
  <pre><code>private DownloadThread[] downloadThreads;
  LockObject lobject = new LockObject(1);
  downloadThreads = new DownloadThread[tableView.getItems().size()];
  for (int i = 0; i &lt; tableView.getItems().size(); i++) {
      UrlModel item = tableView.getItems().get(i);
      downloadThreads[i] = new DownloadThread(lobject,tableView.getItems().size()-i,item.getLink());
      downloadThreads[i].start();
  }
  </code></pre>
  
  <p>Calling lobject.notifyAll() in the run method in Platform.runLater will report an IllegalMonitorStateException. After the address is processed, I want to wake up the next thread to execute.</p>