Reputation: 300
I have two ExecutorService
instances: One with 4 threads and the other, with 20 threads. I want that on a button click, Service 1 stops and waits for Service 2 to end. And afterwards, Service 1 continues to run.
I tried to do this with wait
and notify
but it's not working as expected:
ExecutorService 1:
public void readFile(JTextArea textArea) {
try {
File file = new File(this.fm.fullPath);
if (!file.exists()) {
return;
}
BufferedReader br = new BufferedReader(new FileReader(this.fm.fullPath));
ExecutorService executor = Executors.newFixedThreadPool(main.TOTALSTRINGS);
String line = br.readLine();
int i=1;
while (line != null) {
powThread t = new powThread("Thread" + (i+1), line, textArea);
executor.execute(t);
line = br.readLine();
i++;
}
executor.shutdown();
Thread t = new Thread() {
public void run() {
try {
executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
br.close();
} catch (Exception e) {
}
}
};
t.start();
} catch (IOException e) {
e.printStackTrace();
}
}
ExecutorService2 :
public void generateNumStrings(JTextArea textArea) {
StringGenerator sg = new StringGenerator();
int[] dynamicThreads = main.calcThreadsTotal();
int totalThreads = dynamicThreads.length;
ExecutorService executor = Executors.newFixedThreadPool(totalThreads);
for(int i=0; i<totalThreads; i++) {
generateThread t = new generateThread("Thread" + (i+1), sg, dynamicThreads[i], this.fm);
executor.execute(t);
}
executor.shutdown();
Thread t = new Thread() {
public void run() {
try {
textArea.setText("");
executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
textArea.append("File write successfully!");
} catch (InterruptedException e) {
}
}
};
t.start();
}
Upvotes: 1
Views: 231
Reputation: 18158
You can use an AtomicReference in the first ExecutorService
to wrap the second ExecutorService
or null if the second ExecutorService
hasn't been instantiated, then awaitTermination
if the reference is non-null. I'm assuming that readFile
and generateNumStrings
are in the same class, if not then you'll need to find some way to make the AtomicReference
visible to generateNumStrings
private final AtomicReference<ExecutorService> ref = new AtomicReference<>(null);
private void awaitTermination() throws InterruptedException {
ExecutorService executor = ref.get();
if(executor != null) {
executor.awaitTermination(1, TimeUnit.DAYS);
}
}
public void readFile(JTextArea textArea) {
...
while (line != null) {
awaitTermination();
powThread t = new powThread("Thread" + (i+1), line, textArea);
executor.execute(t);
line = br.readLine();
i++;
}
...
}
public void generateNumStrings(JTextArea textArea) {
...
ExecutorService executor = Executors.newFixedThreadPool(totalThreads);
ref.set(executor);
...
}
Upvotes: 2