Answer the question
In order to leave comments, you need to log in
How to wait for all tasks to complete in order to perform some action in another task?
Task: to design a model of a radiation counter. There are several sensors that read in parallel once per second, the radiation counter should show the average value of all sensors.
At the moment the code is:
import java.util.*;
import java.util.concurrent.*;
class RadiationMeter {
private int value = 0;
private int sensorCounter = 0; // the amount of plugged sensors
private List<Sensor> sensors = new LinkedList<>(); // plugged sensors list
private Thread t = new Thread(new Measuring());
private synchronized void addToValue(int sensorValue) {
value += sensorValue;
}
private class Measuring implements Runnable { // sensors values processing and writing a result
@Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
// waiting until all threads add their values to sensorCounter
// and then dividing by sensorCounter
}
}
}
public void start() { // starting the meter and the sensors
for(Sensor s : sensors)
s.turnOn();
t.start();
}
public class Sensor {
private int value;
private String name;
private final int min; // range of a measurment error
private final int max;
private Thread t;
public Sensor(String name, int min, int max) {
value = 0;
this.min = min;
this.max = max;
this.name = name;
t = new Thread(new Measuring(),name);
if (!sensors.contains(this))
sensors.add(this);
}
public void turnOn() {
RadiationMeter.this.sensorCounter++;
t.start();
}
public void turnOff() {
RadiationMeter.this.sensorCounter--;
t.interrupt();
}
private class Measuring implements Runnable { // measuring by sensor
@Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
addToValue(ThreadLocalRandom.current().nextInt(min, max + 1)); // adding to the meter value
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
return;
}
}
}
}
}
}
public class Program {
public static void main(String[] args) throws Exception {
RadiationMeter rm = new RadiationMeter();
RadiationMeter.Sensor s1 = rm.new Sensor("s1",10,20);
RadiationMeter.Sensor s2 = rm.new Sensor("s2",10,20);
rm.start();
}
}
Answer the question
In order to leave comments, you need to log in
You can use ExecutorService from java.util.concurrent to perform measurement tasks. I tried to sketch.
I have each sensor to perform a measurement creates a measurement task:
public static class Sensor {
private String name;
private int delta = 1;
public Sensor(String name) {
this.name = name;
}
public SensorMeasuring getSensorMeasuringTask() {
return new SensorMeasuring();
}
private class SensorMeasuring implements Callable<Integer> {
@Override
public Integer call() throws Exception {
System.out.println("Запущен сенсор: " + name + " ");
Random random = new Random();
int result = random.nextInt(10) - delta;
System.out.print("Результат: " + result);
return result;
}
}
}
public long getResult(){
List<Callable<Integer>> measuringTasks = new ArrayList<>();
for(Sensor sensor : sensors) {
measuringTasks.add(sensor.getSensorMeasuringTask());
}
List<Future<Integer>> results;
try {
results = executorService.invokeAll(measuringTasks);
return aggregateResults(results);
} catch (InterruptedException e) {
e.printStackTrace();
}
return 0L;
}
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question