2

Я работаю над проектом javaFX, где пользователь просто просматривает несколько файлов, создает их очередь, нажимает на загрузку и загрузку этих файлов по указанному пути. Теперь, когда пользователь нажимает кнопку паузы, процесс загрузки должен быть приостановлен, и когда вы нажмете на резюме, процесс должен быть запущен снова с того места, где он был приостановлен. Итак, до сих пор я создал очередь объектов (файлов) через Executors.newSingleThreadExecutor(); и представил задание. В моем случае класс taks известен как Item. Теперь, когда пользователь нажимает кнопку паузы, я вызываю метод shutdownnow() функции executorService. , и когда пользователь нажимает на резюме, я создаю совершенно новый экземпляр Executorservice. Но когда я отправляю задание с помощью метода executor.execute, он пропускает текущую задачу и возобновляет следующую задачу и так далее. Итак, мне нужно, чтобы это началось с задачи, которую она выполняла последним. Вот код.Приостановка и возобновление работы службы Executor или завершение работы и перезагрузка службы Java-Executor

public class UploadManagerController implements Initializable { 

private static boolean checkRunning = true; 

private static String currentClient; 
private static int currentView = 0; 
private static int checkLastSelectedQueue = 0; 
private static Timeline fiveSecondsWonder; 
private List<File> uploadDir; 
private static long currentSelectedRow = -1; 
private static ThreadFactory threadFactory; 
private static ExecutorService executor; 
private static Thread t; 
private static LinkedHashMap<String, ObservableList> clientUploadInfo; 
private static HashMap<String, Long> clientUploadInfoCount; 
private static HashMap<String, String> clientUploadInfoTotalSize; 
private static HashMap<String, Double> clientUploadInfoTotalSizeLong; 


    public static class Item extends Task<Void> { 

    public SimpleStringProperty fileName = new SimpleStringProperty(); 
    public SimpleStringProperty fileSize = new SimpleStringProperty(); 
    public SimpleStringProperty ETA = new SimpleStringProperty(); 
    public SimpleStringProperty speed = new SimpleStringProperty(); 
    public SimpleStringProperty status = new SimpleStringProperty(); 
    public SimpleDoubleProperty progress = new SimpleDoubleProperty(); 
    public SimpleObjectProperty clientName = new SimpleObjectProperty(); 
    public SimpleStringProperty path = new SimpleStringProperty(); 
    public SimpleLongProperty id = new SimpleLongProperty(); 
    public File file; 
    public long time = 0; 

    // Getter and setter of above variables 

    @Override 
    protected Void call() throws Exception { 
     File filee = this.getFile(); 
     FileInputStream is = new FileInputStream(filee); 
     String mRecordingFile = "UserSpecifiedPath\\" + this.getFileName(); 

     File fl = new File(mRecordingFile); 
     if (fl.exists() && (this.getStatus().equals("error") != true || this.getStatus().equalsIgnoreCase("stopped") != true)) { 
      fl.renameTo(new File("UserSpecifiedPath\\" + Util.getTime() + "_" + fl.getName())); 

     } 

     boolean checkDelete = false; 
     for (String key : clientUploadInfo.keySet()) { 
      if (clientUploadInfo.get(key).contains(this)) { 
       checkDelete = true; 
       break; 
      } 
     } 
     if (checkDelete) { 
      java.nio.channels.FileChannel fc = is.getChannel(); 
      long totalSize = filee.length(); 
      long total = totalSize/10000; 
      java.nio.ByteBuffer bb = java.nio.ByteBuffer.allocate(10000); 

      byte[] bytes; 

      while (fc.read(bb) > 0) { 

       bb.flip(); 
       bytes = bb.array(); 
       File f = new File(mRecordingFile); 
       try (FileOutputStream fOut = new FileOutputStream(mRecordingFile, true)) { 
        fOut.write(bytes); 
       } 
         bb.clear(); 
      } 
     } 


     return null; 
    } 
} 

@Override 
public void initialize(URL url, ResourceBundle rb) { 
    clientUploadInfo = new LinkedHashMap<>(); 
      threadFactory = new ThreadFactory() { 
     @Override 
     public Thread newThread(Runnable r) { 

      t = new Thread(r); 
      try { 
       t.join(); 
      } catch (InterruptedException ex) { 
       System.out.println("inte"); 
      } 
      t.setDaemon(true); 
      return t; 
     } 
    }; 
    executor = Executors.newSingleThreadExecutor(threadFactory); 
} 

    @FXML 
private void startupload(ActionEvent event) { 
    ObservableList<Item> temp = FXCollections.observableArrayList(); 
    temp.addAll(clientUploadInfo.get(currentClient)); 
    currentView = 1; 
    checkRunning = true; 
    if (executor.isShutdown()) { 
     executor = null; 
     t=null; 
     threadFactory = null; 
     threadFactory = new ThreadFactory() { 

      @Override 
      public Thread newThread(Runnable r) { 
       t = new Thread(r); 
       try { 
        t.join(); 
       } catch (InterruptedException ex) { 
        Logger.getLogger(UploadManagerController.class.getName()).log(Level.SEVERE, null, ex); 
       } 

       t.setDaemon(true); 
       return t; 
      } 
     }; 
     executor = Executors.newSingleThreadExecutor(threadFactory); 


     for (Item itm : temp) { 
      if (itm.getStatus().equalsIgnoreCase("In Active") || itm.getStatus().equalsIgnoreCase("queued") || itm.getStatus().equalsIgnoreCase("error") || itm.getStatus().equalsIgnoreCase("stopped")) { 

       executor.submit(itm); 
      } 
     } 

    } else { 
     for (Item itm : temp) { 
      if (itm.getStatus().equalsIgnoreCase("In Active") || itm.getStatus().equalsIgnoreCase("queued") || itm.getStatus().equalsIgnoreCase("error") || itm.getStatus().equalsIgnoreCase("stopped")) { 

       executor.execute(itm); 
      } 
     } 
    } 
} 

@FXML 
private void stopUpload(ActionEvent event) { 
    checkRunning = false; 
    executor.shutdownNow(); 

} 
} 

Извините за мой английский, но позвольте мне объяснить, В приведенном выше коде, их два метода STARTUPLOAD и STOPUPLOAD, эти два метода вызываются по нажатию кнопки JavaFX, поэтому, когда я первый щелчок на кнопке startupload, он начинает загрузку файлов в clientUploadInfo.get (KEY) hasMap, который я поддерживаю при нажатии кнопки добавления файлов, я не упомянул код, чтобы сделать его короче, класс Item несет всю информацию. Нажав на кнопку остановки загрузки, вызывается метод stopUpload, снова нажимаете кнопку запуска загрузить, метод startUpload вызывается, но возобновляет процесс загрузки, помните, что в моем случае он возобновляет загрузку, но из следующего пункта он покидает текущую когда он нажал кнопку «Стоп». Любая помощь будет оценена по достоинству. Спасибо заранее.

+0

Я предлагаю вам отделить свой код gui от своих функций загрузки. Это облегчает проверку и изменение. Это также облегчит понимание другими. Я должен уметь ответить на этот вопрос, не читая ваш код gui. –

+0

Привет, Питер Лоури, я удалил код gui. Пожалуйста, еще раз проверьте – HEAT

ответ

0

Оцените это как ... <? > class, Чтобы приостановить и перезапустить из того же потока, вам нужно получить экземпляр потока с помощью вашего исполнителя и ThreadFactory, Повторная инициализация вашего исполнителя всегда будет пропускать текущий поток, поскольку он все еще находится в памяти, и имеет ссылку на него, даже если вы поместили нуль. Итак, я предлагаю вам попробовать приостановить его, как только закончите текущий поток, покажите всплывающее окно, чтобы доставить сообщение пользователю, что текущий процесс не может быть отменен или в противном случае попытаться переопределить вашу задачу и ThreadFactory и получить идентификатор текущего потока и переустановите только этот поток.

2

Ваше требование состоит в том, чтобы задачи можно было остановить. Я не думаю, что это хорошая идея реализовать это, приостановив (как вы это делаете) исполнитель, потому что приостановление работы исполнителя будет очень опасным в целом (подробности см. В javadoc Thread.suspend()), что, вероятно, Не поддерживайте это.

Гораздо лучше дизайн будет иметь задачи ждать, пока они не должны действовать, например, что-то вроде:

private boolean suspended; 

synchronized void suspend() { 
    suspended = true; 
} 

synchronized void resume() { 
    suspended = false; 
    notifyAll(); 
} 

synchronized void waitWhileSuspended() { 
    while (suspended) { 
     wait(); 
    } 
} 

где задачи будут регулярно ссылаться waitWhileSuspended() времен, где они могут быть безопасно прерваны ,

+0

Итак, должен ли я создать класс класса Runnable, выполнив Runnable. Где бы вы хотели, чтобы я поставил этот код, потому что я пробовал это, он остановил текущую текущую задачу и снова включил ее, но никогда не достигнет следующей задачи. Кроме того, он делает GUI неподходящим во время ожидания. – HEAT

Смежные вопросы