사용자가 파일을 거의 탐색하지 않고 대기열을 만들고 시작 업로드를 클릭하고 지정된 경로에서이 파일의 업로드를 시작하는 javaFX 프로젝트를 작성하고 있습니다. 이제 사용자가 일시 중지 버튼을 클릭하면 업로드 프로세스가 일시 중지되어야하고 다시 시작을 클릭하면 프로세스가 일시 중지 된 시점부터 다시 시작되어야합니다. 그래서 지금까지 Executors.newSingleThreadExecutor()를 통해 Objects (Files) 큐를 만들었습니다. 작업을 제출했습니다. 필자의 경우 taks 클래스는 Item으로 알려져있다. 일시 중지 버튼을 클릭하면 executorService의 shutdownnow() 메소드가 호출됩니다. 사용자가 이력서를 클릭하면 완전히 새로운 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 자신있는 위의 코드에서, 을 설명하려고하자,이 두 가지 방법은 그래서 때 첫 번째 클릭, 자바 FX 버튼의 클릭에 호출 startUpload 버튼을 클릭하면 파일 추가 버튼을 클릭하여 유지 관리하는 clientUploadInfo.get (KEY) hasMap 파일을 업로드하기 시작합니다. 코드를 짧게 만들지는 언급하지 않았으며 Item 클래스는 모든 세부 사항을 전달합니다. 업로드 중지 버튼을 클릭하면 stopUpload 메서드가 호출됩니다. 업로드 시작 버튼을 다시 클릭하면 startUpload 메서드가 호출되지만 업로드 프로세스를 다시 시작합니다. 제 경우에는 업로드를 다시 시작하지만 다음 항목에서 현재 상태를 유지합니다 정지 버튼을 클릭했을 때의 상태를 표시합니다. 도움이 될 것입니다. 미리 감사드립니다.
업로드 기능과 GUI 코드를 분리하는 것이 좋습니다. 이렇게하면 쉽게 테스트하고 변경할 수 있습니다. 이렇게하면 다른 사람들이 쉽게 이해할 수 있습니다. 귀하의 GUI 코드를 읽지 않고이 질문에 대답 할 수 있어야합니다. –
안녕하세요. Peter Lawrey, GUI 코드를 제거했습니다. 다시 확인하십시오. – HEAT