title: Thread is running one after another but not at the same time how can I fix that?
body: <p>I have the following code, which is used to watch a directory and on a creation of a file a thread starts, it should read a CSV file and save the values of it in an object, after that I use the data saved in the object to sort the data from the CSV file in new directory depending on some strategies defined in a config.proprties file, when I paste some files in the directory that is being watched, it gets processed one after another, but what I want is to make them run at the same time unless I have more than one file that will use the same strategy can someone advice what am I doing wrong?</p>
  
  <p>Here is my Watcher class:</p>
  
  <pre><code>    public class MyWatchService extends Thread {
  
          private final Path path;
          private PropertiesValue propertiesValue;
  
          public MyWatchService(Path file) {
              propertiesValue = new PropertiesValue(file.toString());
              this.path = file;
          }
  
          public void doOnChange(String path) {
              String fullPath = MyWatchService.this.path + "/" + path;
  
              Thread thread = new Thread(() -&gt; {
                  try {
                      propertiesValue.validatePatternAndCheckCase(path, fullPath);
                  } catch (Exception e) {
                      System.out.println("Do on changes in the dir: ");
                      e.printStackTrace();
                  }
              });
              thread.start();
          }
  
          @Override
          public void run() {
              try {
                  WatchService watchService = FileSystems.getDefault().newWatchService();
                  path.register(watchService, ENTRY_CREATE);
                  while (true)
                      checkForEvents(watchService);
              } catch (Exception e) {
                  System.out.println("Main Thread: " + e);
              }
          }
  
          private void checkForEvents(java.nio.file.WatchService watchService) {
              try {
                  System.out.println("Waiting for events");
                  WatchKey watchKey = watchService.take();
                  List&lt;WatchEvent&lt;?&gt;&gt; events = watchKey.pollEvents();
                  events.forEach((e) -&gt; getUpdates(e));
                  watchKey.reset();
              } catch (InterruptedException e) {
                  System.out.println("Checking For Events: " + e);
              }
          }
  
          private void getUpdates(WatchEvent&lt;?&gt; e) {
              Path updatedPath = (Path) e.context();
              doOnChange(updatedPath.toString());
          }
      }
  </code></pre>
  
  <p>And here is the class that used to read the property file and match it with file that have been created:</p>
  
  <pre><code>public class PropertiesValue {
  
      private InputStream inputStream;
      private Config config = new Config();
      private String path;
      ReadCSVFile a = new ReadCSVFile();
  
      public PropertiesValue(String path) {
          this.path = path;
      }
  
      private void checkInputStream(Properties properties, String fileName) throws IOException {
          if (inputStream != null)
              properties.load(inputStream);
          else
              throw new FileNotFoundException("property file '" + fileName + "' not found in the classpath");
      }
  
      public void caseCheck(List&lt;Transactions&gt; listOfTrans) throws Exception {
          StratgyImpl strategy = new StratgyImpl();
          config = validatePattern(path);
          String keys = config.getStrategy();
          String path = config.getPath();
          checkStrategy(listOfTrans, strategy, keys, path);
      }
  
  
      private void checkStrategy(List&lt;Transactions&gt; listOfTrans, StratgyImpl strategy, String keys, String path) throws Exception {
          for (Transactions transaction : listOfTrans) {
              if (keys.equals("1")) {
                  path = "/home/user/ATM/" + transaction.getIban() + "/";
                  strategy.imp(1).getDestPathForTransaction(path, transaction,
                          config);// .getDestPathForTransaction(path, t, config);
              } else if (keys.equals("2")) {
                  path = "/home/user/OP/" + transaction.getCurrency() + "/";
                  strategy.imp(2).getDestPathForTransaction(path, transaction,
                          config);//byCurrency.getDestPathForTransaction(path, t, config);
              } else if (keys.equals("3")) {
                  path = "/home/user/PA/" + transaction.getTransactionTime() + "/";
                  strategy.imp(3).getDestPathForTransaction(path, transaction, config);
              } else if (keys.equals("4")) {
                  path = "/home/user/Transactions/" + transaction.getTransactionType() + "/";
                  strategy.imp(4).getDestPathForTransaction(path, transaction,
                          config);//byType.getDestPathForTransaction(path, t, config);
              }
          }
      }
  
      public Config validatePattern(String path) throws IOException {
          try {
              return getConfig(path);
          } catch (Exception e) {
              System.out.println("Validating Pattern Failed: " + e);
          } finally {
              inputStream.close();
          }
          System.out.println("This file does not match any pattern: " + path);
          return null;
      }
  
      public synchronized void validatePatternAndCheckCase(String path, String fullPath) throws Exception {
          validatePattern(path);
          caseCheck(a.readFile(fullPath));
      }
  
      private Config getConfig(String path) throws IOException {
          Properties properties;
          String fileName;
          Set&lt;String&gt; value;
          properties = new Properties();
          fileName = "config.properties";
          inputStream = getClass().getClassLoader().getResourceAsStream(fileName);
          checkInputStream(properties, fileName);
          value = properties.stringPropertyNames();
          getStrategyAndPath(path, properties, value);
          return config;
      }
  
      private void getStrategyAndPath(String path, Properties properties, Set&lt;String&gt; value) {
          String key;
          String[] strings;
          for (String val : value) {
              key = (String) properties.get(val);
              strings = key.split(",");
              if (path.matches(val)) {
                  config.setStrategy(strings[0]);
                  config.setPath(strings[1]);
              }
          }
      }
  }
  </code></pre>
  
  <p>And here is my strategy implementation class:</p>
  
  <pre><code>public class StratgyImpl {
  
      WriteCSV w = new WriteCSV();
  
      public Strategies imp(int id) throws Exception {
          if (id == 1) {
              return (path, transaction, config) -&gt; {
                  Path newPath;
                  if (config != null) {
                      newPath = Paths.get(path.toString());
                      w.writeFile(transaction, path);
                      return newPath;
                  }
                  throw new IllegalPathStateException("Path not found: " + path);
              };
          } else if (id == 2) {
              return (path, transaction, config) -&gt; {
                  Path newPath;
                  if (config != null) {
                      newPath = Paths.get(path.toString());
                      w.writeFile(transaction, path);
                      return newPath;
                  }
                  throw new IllegalPathStateException("Path not found: " + path);
              };
          } else if (id == 3) {
              return (path, transaction, config) -&gt; {
                  Path newPath;
                  if (config != null) {
                      newPath = Paths.get(path.toString());
                      w.writeFile(transaction, path);
                      return newPath;
                  }
                  throw new IllegalPathStateException("Path not found: " + path);
              };
          } else if (id == 4) {
              return (path, transaction, config) -&gt; {
                  Path newPath;
                  if (config != null) {
                      newPath = Paths.get(path.toString());
                      w.writeFileByTransactionType(transaction, path);
                      return newPath;
                  }
                  throw new IllegalPathStateException("Path not found: " + path);
              };
  
          }
          throw new Exception("Could not find the requested strategy");
      }
  }
  </code></pre>
  
  <p>When I run the code I get the following result:</p>
  
  <pre><code>Thread Name = Thread-2
  Thread Name = Thread-2
  Thread Name = Thread-2
  Thread Name = Thread-2
  Thread Name = Thread-2
  Thread Name = Thread-5
  Thread Name = Thread-5
  Thread Name = Thread-5
  Thread Name = Thread-5
  Thread Name = Thread-5
  Thread Name = Thread-4
  Thread Name = Thread-4
  Thread Name = Thread-4
  Thread Name = Thread-4
  Thread Name = Thread-4
  Thread Name = Thread-3
  Thread Name = Thread-3
  Thread Name = Thread-3
  Thread Name = Thread-3
  Thread Name = Thread-3
  </code></pre>
  
  <p>While all the files have a different strategies to implement!
  If someone is interested to help please let me know if you want to see more code :)</p>