My task is to read three files from three threads using the synchronized keyword. This is my code that I am using, however, when I print "SumOfTheFiles", it is printing 0. What am I doing wrong ?
public class Dispatcher {
public static void main(String[] args) {
ExecutorService executorService = Executors.newCachedThreadPool();
executorService.execute(new Thread(new SumOfDigits(new File("text.txt"))));
executorService.execute(new Thread(new SumOfDigits(new File("text2.txt"))));
executorService.execute(new Thread(new SumOfDigits(new File("text3.txt"))));
executorService.shutdown();
System.out.println(SumOfDigits.SumOFTheFiles);
}
}
class SumOfDigits implements Runnable {
File file;
static int SumOFTheFiles = 0;
public SumOfDigits(File file) {
this.file = file;
}
@Override
public void run() {
SumOFTheFiles = sum();
}
synchronized int sum() {
int sum = 0;
try(Scanner sc = new Scanner(file)){
while(sc.hasNext()){
sum = Integer.parseInt(sc.next());
}
}catch (Exception e){
e.printStackTrace();
}
return sum;
}
}
CodePudding user response:
The issue here is that you not are enforcing synchronized access to the SumOfTheFiles
variable. You are calculating the sum in a synchronized block, however, you are accessing the variable in the asynchronous run methods. To prevent this, update the SumOfTheFiles
variable in the sum method.
Example:
public class ThreadTest {
public static void main(String[] args) {
Thread s1 = new Thread(new SumOfDigits(new File("f1.txt")));
Thread s2 = new Thread(new SumOfDigits(new File("f2.txt")));
Thread s3 = new Thread(new SumOfDigits(new File("f3.txt")));
// Run the threads
s1.start();
s2.start();
s3.start();
// Wait for completion
try {
s1.join();
s2.join();
s3.join();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(SumOfDigits.SumOFTheFiles);
}
}
class SumOfDigits implements Runnable {
static int SumOFTheFiles = 0;
File aFile;
@Override
public void run() {
this.sum();
}
public SumOfDigits(File aFile) {
this.aFile = aFile;
}
// New sum method
synchronized void sum() {
int sum = 0;
try {
Scanner sc = new Scanner(this.aFile);
while(sc.hasNextInt()){
sum = sc.nextInt();
}
sc.close();
} catch (Exception e) {
e.printStackTrace();
}
SumOFTheFiles = sum;
}
}
The output of this code is always 74 given f1 contains "9 9 9 9 9", f2 contains "8 8 8", and f3 contains "3 2".