Issue
I want to make a test program with CompletableFuture
. I have a class with 2 functions:
public class FutureTextData {
private ConcurrentHashMap<String,Integer> map = new ConcurrentHashMap<>();
private CompletableFuture<Void> futureForText;
public void getCharInText(String text){
futureForText = CompletableFuture.runAsync(() -> {
for (int i = 0; i < text.length()-3; i++) {
map.compute(text.substring(i+1),(key,value) -> value+=1);
map.compute(text.substring(i+2),(key,value) -> value+=1);
map.compute(text.substring(i+3),(key,value) -> value+=1);
}
for(Map.Entry<String ,Integer> entry:map.entrySet()){
if(entry.getKey().length()==3)
System.out.println(entry.getKey());
}
});
}
public void recordCharInText(String outPutFile){
/*try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}*/
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
File file = new File(outPutFile);
try(BufferedWriter bf = new BufferedWriter(new FileWriter(file))){
for(Map.Entry<String ,Integer> entry:map.entrySet()){
bf.write(entry.getKey() +"<----->" + entry.getValue());
}
}catch (IOException e) {
e.printStackTrace();
}
});
}
}
In getCharInText()
, I want to count the number of certain substrings in the text, and in recordCharInText()
I want to record the current state of the Map.
And when I run the program:
FutureTextData futureTextData = new FutureTextData();
futureTextData.getCharInText(result);
futureTextData.recordCharInText("outFile.txt");
Then everything just completes without errors and everything. i.e. map is not written to the file, and getCharInText()
is not even executed.
Can you tell me what the error is?
Solution
The ForkJoinPool
CommonPool
which runs your tasks will shut down when the program exits:
/**
* Returns the common pool instance. This pool is statically
* constructed; its run state is unaffected by attempts to {@link
* #shutdown} or {@link #shutdownNow}. However this pool and any
* ongoing processing are automatically terminated upon program
* {@link System#exit}. Any program that relies on asynchronous
* task processing to complete before program termination should
* invoke {@code commonPool().}{@link #awaitQuiescence awaitQuiescence},
* before exit.
*
* @return the common pool instance
* @since 1.8
*/
public static ForkJoinPool commonPool() {
// assert common != null : "static init error";
return common;
}
If I modify your code to add awaitQuiescence
and log the execution of the tasks I get:
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.*;
public class FutureTextData {
private ConcurrentHashMap<String,Integer> map = new ConcurrentHashMap<>();
public CompletableFuture<Void> futureForText;
public void getCharInText(String text){
futureForText = CompletableFuture.runAsync(() -> {
System.out.println("Running first task");
map.put("foo", 1);
});
}
public void recordCharInText(String outPutFile){
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
System.out.println("Running second task");
File file = new File(outPutFile);
try(BufferedWriter bf = new BufferedWriter(new FileWriter(file))){
for(Map.Entry<String ,Integer> entry:map.entrySet()){
bf.write(entry.getKey() +"<----->" + entry.getValue());
}
} catch (IOException e) {
throw new RuntimeException(e);
}
});
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
FutureTextData futureTextData = new FutureTextData();
futureTextData.getCharInText("xyz");
futureTextData.recordCharInText("outFile.txt");
ForkJoinPool.commonPool().awaitQuiescence(1000, TimeUnit.MILLISECONDS);
}
}
which produces:
Running first task
Running second task
Process finished with exit code 0
Answered By - tgdavies
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.