0

There are two separate threads in my code that are using there own Executor's SingleThreadExecutor. I wanted that both those services should run parallelly, but what I observed that one service haults then only the second service starts and when the second service haults then only the first one starts. I have not used any locking system.

So, do we achieve Concurrency, with SingleThreadExecutors or Parallelism? Should I consider CompletableFuture.runAsync() in my application, to run the tasks parallelly?

Yash Bansal
  • 402
  • 5
  • 10
  • Please provide a [mre], along with how you're testing the execution and information such as how many cores your computer has. – Slaw Jun 20 '19 at 15:34
  • Here's a minimal reproducible example corresponding to your description. But of course, it doesn't reproduce your prolem: both tasks do execute concurrently. So it's a problem in your code, but you haven't posted it... https://ideone.com/Wmg6wi – JB Nizet Jun 20 '19 at 15:41
  • Thanks Slaw, I am using a 4 core machine. The two services are in my web application. One service gets the data from a queue and submits to another queue from where other service picks it up and stores that data in DB. So, if both the queue has some job in them, both the services should run in parallel. But first service runs and empties the queue till then another queue builds up. After first becomes empty, second service starts picking up the job from 2nd queue and by that time first queue grows. – Yash Bansal Jun 20 '19 at 15:46
  • @JBNizet, Thanks for the code, but that does not guarantees the parallelism right? The two task in the code you mentioned can be concurrent, one runs then another runs... – Yash Bansal Jun 20 '19 at 15:49
  • Just look at the output: `i = 0 i = 0 i = 1 i = 1 i = 2 i = 2...`. If they ran one after the other, you would have `i = 0 i = 1 i = 2... i = 0 i = 1 i = 2...` – JB Nizet Jun 20 '19 at 15:51
  • @JBNizet, I think this is the illusion that concurrency gives us, it depends on when a thread is getting the CPU – Yash Bansal Jun 20 '19 at 15:54
  • The OS is free to dispatch threads to cores the way it wants to. And there are plenty of other threads running on your OS in addition to your two threads. But there is no reason for your threads to execute in a mutual exclusive way if they are independant. Are they? Without any code, impossible to tell. – JB Nizet Jun 20 '19 at 16:01
  • Yeah, thats what my question is so if I use SingleThreadExecutor is parallelism guaranteed or should I use CompletableFuture.runAsync(). And lets say in an idle scenario where only these services are running. – Yash Bansal Jun 20 '19 at 16:04
  • Objects such as `ExecutorService` simply encapsulate the use of threads, usually providing a reusable pool. Using `CompletableFuture.runAsync` will either use the common `ForkJoinPool`—which is an `ExecutorService`—or whatever `Executor` you provide it with. The important part is if your code is being executed by a different `Thread`. If you're using a single-threaded `ExecutorService` then that service can only execute one task at a time because it only has one thread. Other threads are allowed to execute in parallel—including threads belonging to another `ExecutorService`. – Slaw Jun 20 '19 at 16:17
  • If you're convinced your code is not executing in parallel when it should be running in parallel, then please [edit] your question to provide a [mre]. – Slaw Jun 20 '19 at 16:18
  • @Slaw, its not about the code, I am asking. My question is in general whether SingleThreadExecutors or CachedThreadPool or FixedThreadPool guarantees parallelism. From the comments I can conclude that they guarantees parallelism not just concurrency. – Yash Bansal Jun 20 '19 at 16:22
  • They guarantee _concurrency_ but not _parallelism_. Whether or not the tasks execute in parallel depends on if your computer has enough cores/processors and how the OS schedules the threads. If all your threads are scheduled to a single core/processor then your code is not executing in parallel—no matter how many `Thread`s you use. – Slaw Jun 20 '19 at 16:26
  • Thanks Slaw, this is what I am looking for. So lets say, if I have 4 cores, then how can I make sure that the threads should be scheduled on different cores, which library should I use for that. – Yash Bansal Jun 20 '19 at 16:27
  • Again: the OS is free to dispatch threads to cores the way it wants to. And it can also redispatch threads on different cores. – JB Nizet Jun 20 '19 at 16:33
  • **You** don't make sure. _The OS is responsible for scheduling threads._ All you need to do is program your application to use threads. No matter what Java library you use they will all use the same mechanism: `java.lang.Thread`. – Slaw Jun 20 '19 at 16:33
  • That means parallelism can never be guaranteed, it all depends on the OS. Then why do we say by using streams, promises and ForkJoinPool w achieve Parallelism. – Yash Bansal Jun 20 '19 at 16:39
  • That I can't answer definitively. Could be any number of reasons: confusing the terminology, believing the two terms are interchangeable, person who wrote that is not a computer scientist/software developer and isn't familiar enough with the field, defining the two terms differently for some reason, that multi-processor machines are ubiquitous these days and thus parallelism might as well be "guaranteed", etc.... Notice that in Java the concurrency classes are located in `java.util` **`.concurrent`**. – Slaw Jun 20 '19 at 17:00
  • A SingleThreadExecutor by definition only uses a single thread, so tasks cannot be executed in parallel... – Mark Rotteveel Jun 22 '19 at 12:46
  • In my travels since this comment thread, I've come across [this question](https://stackoverflow.com/questions/2238272/java-thread-affinity); it points to the use of native code to set thread affinity. May help you, may not. However, it's unlikely you need to care about such things when using Java—just let the OS schedule the threads at it sees fit. – Slaw Jun 23 '19 at 11:23
  • Sure Slaw, I will check that – Yash Bansal Jun 26 '19 at 00:06

0 Answers0