Why task is done when first element in the future list is true?












1















I'm little confused with tasks in Java multithreading.
Namely, I've 15 objects, which implements Callable and i'm submitting it by ExecutorService. Each Callable has its own progress bar with is updating in for loop with setProgress method.
I want to show 3 of 15 callables which will finish their job in first, second and third position by getting their names and setting it to labels on my scene. Of course each callable has different working time.



I created Task and i'm starting it in new thread and iterating over list of future tasks from my ExecutorService.
The problem is that my labels aren't visible until first element of the future list is true (until first thread is finished). I have really no idea why and i would be very grateful for your help.



public void startButtonClicked() {
Task task = new Task<Void>() {
@Override
public Void call() {
int i = 0;
while (i < 3) {
for (Future<Boolean> future : futures) {
try {
if (future.get() == true && i == 0) {
labelFirst.setVisible(true);
i++;
}

if (future.get() == true && i == 1) {
labelSecond.setVisible(true);
i++;
}

if (future.get() == true && i == 2) {
labelThird.setVisible(true);
i++;
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}

return null;
}
};

for (Callable c : callables) {
futures.add(executorService.submit(c));
}
new Thread(task).start();

executorService.shutdown();
}


In my ideal solution each label will become visible when their callable will finish, so labelSecond should appear some time after labelFirst.
It's my call method in my callable:



public Boolean call() {
double raceTime = ThreadLocalRandom.current().nextDouble(45.0, 60.0);

try {
for (double i = 0; i < raceTime; i += 0.01) {
TimeUnit.MILLISECONDS.sleep(1);
progressBar.setProgress(i / raceTime);
}
} catch (ParseException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}

return true;
}


EDIT:
With checking future.isDone() and little changes it works as i wished.



public void startButtonClicked() {
Task task = new Task<Void>() {
@Override
public Void call() {
int i = 0;
while (i < 3) {
i = 0;
for (Future<Boolean> future : futures) {
if (future.isDone() == true) i++;

if (i == 1) {
labelFirst.setVisible(true);
labelFirstCyclistName.setVisible(true);
}

if (i == 2) {
labelSecond.setVisible(true);
labelSecondCyclistName.setVisible(true);
}

if (i == 3) {
labelThird.setVisible(true);
labelThirdCyclistName.setVisible(true);
}
}
}

return null;
}
};

for (Cyclist c : cyclists) {
futures.add(executorService.submit(c));
}
new Thread(task).start();

executorService.shutdown();
}









share|improve this question

























  • I'm not quite sure I understand what the code is supposed to be doing, but know that Future.get is a blocking call. The method won't return until the Future's task has completed either exceptionally (in which case an exception is thrown) or normally (in which case the value is returned).

    – Slaw
    Dec 28 '18 at 21:55













  • Also, you are calling setVisible on a background thread. You must only modify GUI state on the JavaFX Application Thread. You can do this with Platform.runLater.

    – Slaw
    Dec 28 '18 at 21:58











  • Should I call this task which is checking Future List in Platform.runLater? Or updateing progressbars?

    – NIGHTHAWK
    Dec 29 '18 at 10:37











  • You should only wrap the code modifying the GUI in Platform.runLater (see Concurrency in JavaFX). Note that Task has properties/methods for communicating with the GUI in this manner (e.g. updateProgress, updateMessage, etc...). They not only run the updates on the JavaFX Application Thread but they also coalesce updates to avoid flooding the FX thread with too much work.

    – Slaw
    Dec 29 '18 at 23:43


















1















I'm little confused with tasks in Java multithreading.
Namely, I've 15 objects, which implements Callable and i'm submitting it by ExecutorService. Each Callable has its own progress bar with is updating in for loop with setProgress method.
I want to show 3 of 15 callables which will finish their job in first, second and third position by getting their names and setting it to labels on my scene. Of course each callable has different working time.



I created Task and i'm starting it in new thread and iterating over list of future tasks from my ExecutorService.
The problem is that my labels aren't visible until first element of the future list is true (until first thread is finished). I have really no idea why and i would be very grateful for your help.



public void startButtonClicked() {
Task task = new Task<Void>() {
@Override
public Void call() {
int i = 0;
while (i < 3) {
for (Future<Boolean> future : futures) {
try {
if (future.get() == true && i == 0) {
labelFirst.setVisible(true);
i++;
}

if (future.get() == true && i == 1) {
labelSecond.setVisible(true);
i++;
}

if (future.get() == true && i == 2) {
labelThird.setVisible(true);
i++;
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}

return null;
}
};

for (Callable c : callables) {
futures.add(executorService.submit(c));
}
new Thread(task).start();

executorService.shutdown();
}


In my ideal solution each label will become visible when their callable will finish, so labelSecond should appear some time after labelFirst.
It's my call method in my callable:



public Boolean call() {
double raceTime = ThreadLocalRandom.current().nextDouble(45.0, 60.0);

try {
for (double i = 0; i < raceTime; i += 0.01) {
TimeUnit.MILLISECONDS.sleep(1);
progressBar.setProgress(i / raceTime);
}
} catch (ParseException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}

return true;
}


EDIT:
With checking future.isDone() and little changes it works as i wished.



public void startButtonClicked() {
Task task = new Task<Void>() {
@Override
public Void call() {
int i = 0;
while (i < 3) {
i = 0;
for (Future<Boolean> future : futures) {
if (future.isDone() == true) i++;

if (i == 1) {
labelFirst.setVisible(true);
labelFirstCyclistName.setVisible(true);
}

if (i == 2) {
labelSecond.setVisible(true);
labelSecondCyclistName.setVisible(true);
}

if (i == 3) {
labelThird.setVisible(true);
labelThirdCyclistName.setVisible(true);
}
}
}

return null;
}
};

for (Cyclist c : cyclists) {
futures.add(executorService.submit(c));
}
new Thread(task).start();

executorService.shutdown();
}









share|improve this question

























  • I'm not quite sure I understand what the code is supposed to be doing, but know that Future.get is a blocking call. The method won't return until the Future's task has completed either exceptionally (in which case an exception is thrown) or normally (in which case the value is returned).

    – Slaw
    Dec 28 '18 at 21:55













  • Also, you are calling setVisible on a background thread. You must only modify GUI state on the JavaFX Application Thread. You can do this with Platform.runLater.

    – Slaw
    Dec 28 '18 at 21:58











  • Should I call this task which is checking Future List in Platform.runLater? Or updateing progressbars?

    – NIGHTHAWK
    Dec 29 '18 at 10:37











  • You should only wrap the code modifying the GUI in Platform.runLater (see Concurrency in JavaFX). Note that Task has properties/methods for communicating with the GUI in this manner (e.g. updateProgress, updateMessage, etc...). They not only run the updates on the JavaFX Application Thread but they also coalesce updates to avoid flooding the FX thread with too much work.

    – Slaw
    Dec 29 '18 at 23:43
















1












1








1








I'm little confused with tasks in Java multithreading.
Namely, I've 15 objects, which implements Callable and i'm submitting it by ExecutorService. Each Callable has its own progress bar with is updating in for loop with setProgress method.
I want to show 3 of 15 callables which will finish their job in first, second and third position by getting their names and setting it to labels on my scene. Of course each callable has different working time.



I created Task and i'm starting it in new thread and iterating over list of future tasks from my ExecutorService.
The problem is that my labels aren't visible until first element of the future list is true (until first thread is finished). I have really no idea why and i would be very grateful for your help.



public void startButtonClicked() {
Task task = new Task<Void>() {
@Override
public Void call() {
int i = 0;
while (i < 3) {
for (Future<Boolean> future : futures) {
try {
if (future.get() == true && i == 0) {
labelFirst.setVisible(true);
i++;
}

if (future.get() == true && i == 1) {
labelSecond.setVisible(true);
i++;
}

if (future.get() == true && i == 2) {
labelThird.setVisible(true);
i++;
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}

return null;
}
};

for (Callable c : callables) {
futures.add(executorService.submit(c));
}
new Thread(task).start();

executorService.shutdown();
}


In my ideal solution each label will become visible when their callable will finish, so labelSecond should appear some time after labelFirst.
It's my call method in my callable:



public Boolean call() {
double raceTime = ThreadLocalRandom.current().nextDouble(45.0, 60.0);

try {
for (double i = 0; i < raceTime; i += 0.01) {
TimeUnit.MILLISECONDS.sleep(1);
progressBar.setProgress(i / raceTime);
}
} catch (ParseException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}

return true;
}


EDIT:
With checking future.isDone() and little changes it works as i wished.



public void startButtonClicked() {
Task task = new Task<Void>() {
@Override
public Void call() {
int i = 0;
while (i < 3) {
i = 0;
for (Future<Boolean> future : futures) {
if (future.isDone() == true) i++;

if (i == 1) {
labelFirst.setVisible(true);
labelFirstCyclistName.setVisible(true);
}

if (i == 2) {
labelSecond.setVisible(true);
labelSecondCyclistName.setVisible(true);
}

if (i == 3) {
labelThird.setVisible(true);
labelThirdCyclistName.setVisible(true);
}
}
}

return null;
}
};

for (Cyclist c : cyclists) {
futures.add(executorService.submit(c));
}
new Thread(task).start();

executorService.shutdown();
}









share|improve this question
















I'm little confused with tasks in Java multithreading.
Namely, I've 15 objects, which implements Callable and i'm submitting it by ExecutorService. Each Callable has its own progress bar with is updating in for loop with setProgress method.
I want to show 3 of 15 callables which will finish their job in first, second and third position by getting their names and setting it to labels on my scene. Of course each callable has different working time.



I created Task and i'm starting it in new thread and iterating over list of future tasks from my ExecutorService.
The problem is that my labels aren't visible until first element of the future list is true (until first thread is finished). I have really no idea why and i would be very grateful for your help.



public void startButtonClicked() {
Task task = new Task<Void>() {
@Override
public Void call() {
int i = 0;
while (i < 3) {
for (Future<Boolean> future : futures) {
try {
if (future.get() == true && i == 0) {
labelFirst.setVisible(true);
i++;
}

if (future.get() == true && i == 1) {
labelSecond.setVisible(true);
i++;
}

if (future.get() == true && i == 2) {
labelThird.setVisible(true);
i++;
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}

return null;
}
};

for (Callable c : callables) {
futures.add(executorService.submit(c));
}
new Thread(task).start();

executorService.shutdown();
}


In my ideal solution each label will become visible when their callable will finish, so labelSecond should appear some time after labelFirst.
It's my call method in my callable:



public Boolean call() {
double raceTime = ThreadLocalRandom.current().nextDouble(45.0, 60.0);

try {
for (double i = 0; i < raceTime; i += 0.01) {
TimeUnit.MILLISECONDS.sleep(1);
progressBar.setProgress(i / raceTime);
}
} catch (ParseException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}

return true;
}


EDIT:
With checking future.isDone() and little changes it works as i wished.



public void startButtonClicked() {
Task task = new Task<Void>() {
@Override
public Void call() {
int i = 0;
while (i < 3) {
i = 0;
for (Future<Boolean> future : futures) {
if (future.isDone() == true) i++;

if (i == 1) {
labelFirst.setVisible(true);
labelFirstCyclistName.setVisible(true);
}

if (i == 2) {
labelSecond.setVisible(true);
labelSecondCyclistName.setVisible(true);
}

if (i == 3) {
labelThird.setVisible(true);
labelThirdCyclistName.setVisible(true);
}
}
}

return null;
}
};

for (Cyclist c : cyclists) {
futures.add(executorService.submit(c));
}
new Thread(task).start();

executorService.shutdown();
}






java multithreading






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Dec 29 '18 at 10:15







NIGHTHAWK

















asked Dec 28 '18 at 21:12









NIGHTHAWKNIGHTHAWK

85




85













  • I'm not quite sure I understand what the code is supposed to be doing, but know that Future.get is a blocking call. The method won't return until the Future's task has completed either exceptionally (in which case an exception is thrown) or normally (in which case the value is returned).

    – Slaw
    Dec 28 '18 at 21:55













  • Also, you are calling setVisible on a background thread. You must only modify GUI state on the JavaFX Application Thread. You can do this with Platform.runLater.

    – Slaw
    Dec 28 '18 at 21:58











  • Should I call this task which is checking Future List in Platform.runLater? Or updateing progressbars?

    – NIGHTHAWK
    Dec 29 '18 at 10:37











  • You should only wrap the code modifying the GUI in Platform.runLater (see Concurrency in JavaFX). Note that Task has properties/methods for communicating with the GUI in this manner (e.g. updateProgress, updateMessage, etc...). They not only run the updates on the JavaFX Application Thread but they also coalesce updates to avoid flooding the FX thread with too much work.

    – Slaw
    Dec 29 '18 at 23:43





















  • I'm not quite sure I understand what the code is supposed to be doing, but know that Future.get is a blocking call. The method won't return until the Future's task has completed either exceptionally (in which case an exception is thrown) or normally (in which case the value is returned).

    – Slaw
    Dec 28 '18 at 21:55













  • Also, you are calling setVisible on a background thread. You must only modify GUI state on the JavaFX Application Thread. You can do this with Platform.runLater.

    – Slaw
    Dec 28 '18 at 21:58











  • Should I call this task which is checking Future List in Platform.runLater? Or updateing progressbars?

    – NIGHTHAWK
    Dec 29 '18 at 10:37











  • You should only wrap the code modifying the GUI in Platform.runLater (see Concurrency in JavaFX). Note that Task has properties/methods for communicating with the GUI in this manner (e.g. updateProgress, updateMessage, etc...). They not only run the updates on the JavaFX Application Thread but they also coalesce updates to avoid flooding the FX thread with too much work.

    – Slaw
    Dec 29 '18 at 23:43



















I'm not quite sure I understand what the code is supposed to be doing, but know that Future.get is a blocking call. The method won't return until the Future's task has completed either exceptionally (in which case an exception is thrown) or normally (in which case the value is returned).

– Slaw
Dec 28 '18 at 21:55







I'm not quite sure I understand what the code is supposed to be doing, but know that Future.get is a blocking call. The method won't return until the Future's task has completed either exceptionally (in which case an exception is thrown) or normally (in which case the value is returned).

– Slaw
Dec 28 '18 at 21:55















Also, you are calling setVisible on a background thread. You must only modify GUI state on the JavaFX Application Thread. You can do this with Platform.runLater.

– Slaw
Dec 28 '18 at 21:58





Also, you are calling setVisible on a background thread. You must only modify GUI state on the JavaFX Application Thread. You can do this with Platform.runLater.

– Slaw
Dec 28 '18 at 21:58













Should I call this task which is checking Future List in Platform.runLater? Or updateing progressbars?

– NIGHTHAWK
Dec 29 '18 at 10:37





Should I call this task which is checking Future List in Platform.runLater? Or updateing progressbars?

– NIGHTHAWK
Dec 29 '18 at 10:37













You should only wrap the code modifying the GUI in Platform.runLater (see Concurrency in JavaFX). Note that Task has properties/methods for communicating with the GUI in this manner (e.g. updateProgress, updateMessage, etc...). They not only run the updates on the JavaFX Application Thread but they also coalesce updates to avoid flooding the FX thread with too much work.

– Slaw
Dec 29 '18 at 23:43







You should only wrap the code modifying the GUI in Platform.runLater (see Concurrency in JavaFX). Note that Task has properties/methods for communicating with the GUI in this manner (e.g. updateProgress, updateMessage, etc...). They not only run the updates on the JavaFX Application Thread but they also coalesce updates to avoid flooding the FX thread with too much work.

– Slaw
Dec 29 '18 at 23:43














1 Answer
1






active

oldest

votes


















0















The problem is that my labels aren't visible until first element of
the future list is true (until first thread is finished). I have
really no idea why and i would be very grateful for your help.






According to the documentation of Future#get




Waits if necessary for the computation to complete, and then retrieves
its result.






Here is your code - pay special attention to a line containing future.get():



public Void call() {
int i = 0;
while (i < 3) {
for (Future<Boolean> future : futures) {
try {
if (future.get() == true && i == 0) {


During the first iteration of the loop the first future is retrieved from futures, and then future.get() stops the execution of the loop and waits (holds) until execution of this first future (the first thread) will finish and will return a result.

Then the loop continues and LabelX..setVisible(true); are called making labels visible.






share|improve this answer
























  • I see, that make sense - i was waiting in future.get(). Name of the method has totally misleaded me and it's my fault because i didn't check it in documentation. Now with checking future.isDone() its work pretty well. Thank you.

    – NIGHTHAWK
    Dec 29 '18 at 10:12













Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53964333%2fwhy-task-is-done-when-first-element-in-the-future-list-is-true%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









0















The problem is that my labels aren't visible until first element of
the future list is true (until first thread is finished). I have
really no idea why and i would be very grateful for your help.






According to the documentation of Future#get




Waits if necessary for the computation to complete, and then retrieves
its result.






Here is your code - pay special attention to a line containing future.get():



public Void call() {
int i = 0;
while (i < 3) {
for (Future<Boolean> future : futures) {
try {
if (future.get() == true && i == 0) {


During the first iteration of the loop the first future is retrieved from futures, and then future.get() stops the execution of the loop and waits (holds) until execution of this first future (the first thread) will finish and will return a result.

Then the loop continues and LabelX..setVisible(true); are called making labels visible.






share|improve this answer
























  • I see, that make sense - i was waiting in future.get(). Name of the method has totally misleaded me and it's my fault because i didn't check it in documentation. Now with checking future.isDone() its work pretty well. Thank you.

    – NIGHTHAWK
    Dec 29 '18 at 10:12


















0















The problem is that my labels aren't visible until first element of
the future list is true (until first thread is finished). I have
really no idea why and i would be very grateful for your help.






According to the documentation of Future#get




Waits if necessary for the computation to complete, and then retrieves
its result.






Here is your code - pay special attention to a line containing future.get():



public Void call() {
int i = 0;
while (i < 3) {
for (Future<Boolean> future : futures) {
try {
if (future.get() == true && i == 0) {


During the first iteration of the loop the first future is retrieved from futures, and then future.get() stops the execution of the loop and waits (holds) until execution of this first future (the first thread) will finish and will return a result.

Then the loop continues and LabelX..setVisible(true); are called making labels visible.






share|improve this answer
























  • I see, that make sense - i was waiting in future.get(). Name of the method has totally misleaded me and it's my fault because i didn't check it in documentation. Now with checking future.isDone() its work pretty well. Thank you.

    – NIGHTHAWK
    Dec 29 '18 at 10:12
















0












0








0








The problem is that my labels aren't visible until first element of
the future list is true (until first thread is finished). I have
really no idea why and i would be very grateful for your help.






According to the documentation of Future#get




Waits if necessary for the computation to complete, and then retrieves
its result.






Here is your code - pay special attention to a line containing future.get():



public Void call() {
int i = 0;
while (i < 3) {
for (Future<Boolean> future : futures) {
try {
if (future.get() == true && i == 0) {


During the first iteration of the loop the first future is retrieved from futures, and then future.get() stops the execution of the loop and waits (holds) until execution of this first future (the first thread) will finish and will return a result.

Then the loop continues and LabelX..setVisible(true); are called making labels visible.






share|improve this answer














The problem is that my labels aren't visible until first element of
the future list is true (until first thread is finished). I have
really no idea why and i would be very grateful for your help.






According to the documentation of Future#get




Waits if necessary for the computation to complete, and then retrieves
its result.






Here is your code - pay special attention to a line containing future.get():



public Void call() {
int i = 0;
while (i < 3) {
for (Future<Boolean> future : futures) {
try {
if (future.get() == true && i == 0) {


During the first iteration of the loop the first future is retrieved from futures, and then future.get() stops the execution of the loop and waits (holds) until execution of this first future (the first thread) will finish and will return a result.

Then the loop continues and LabelX..setVisible(true); are called making labels visible.







share|improve this answer












share|improve this answer



share|improve this answer










answered Dec 28 '18 at 21:56









krokodilkokrokodilko

28.4k32757




28.4k32757













  • I see, that make sense - i was waiting in future.get(). Name of the method has totally misleaded me and it's my fault because i didn't check it in documentation. Now with checking future.isDone() its work pretty well. Thank you.

    – NIGHTHAWK
    Dec 29 '18 at 10:12





















  • I see, that make sense - i was waiting in future.get(). Name of the method has totally misleaded me and it's my fault because i didn't check it in documentation. Now with checking future.isDone() its work pretty well. Thank you.

    – NIGHTHAWK
    Dec 29 '18 at 10:12



















I see, that make sense - i was waiting in future.get(). Name of the method has totally misleaded me and it's my fault because i didn't check it in documentation. Now with checking future.isDone() its work pretty well. Thank you.

– NIGHTHAWK
Dec 29 '18 at 10:12







I see, that make sense - i was waiting in future.get(). Name of the method has totally misleaded me and it's my fault because i didn't check it in documentation. Now with checking future.isDone() its work pretty well. Thank you.

– NIGHTHAWK
Dec 29 '18 at 10:12




















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53964333%2fwhy-task-is-done-when-first-element-in-the-future-list-is-true%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Mossoró

Can't read property showImagePicker of undefined in react native iOS

Pushsharp Apns notification error: 'InvalidToken'