What is the difference between executing ExecutorService and thread.run while running threads in Java at the same time?

I am new to this concurrent programming in java and have come up with the following scripts where I get confusion which will be used when.

Scenario 1: In the following code, I tried to start streams by calling .start () in the GPSService class, which is a Runnable implementation.

int clientNumber = 0; ServerSocket listener = new ServerSocket(port); while (true) { new GPSService(listener.accept(), clientNumber++, serverUrl).start(); } 

Scenario 2: In the following code, I tried to start threads using the ExecutorService class, as shown

 int clientNumber = 0; ServerSocket listener = new ServerSocket(port); while(true) { ExecutorService executor = Executors.newSingleThreadExecutor(); executor.execute(new GPSService(listener.accept(), client++, serverUrl)); executor.shutdown(); while (!executor.awaitTermination(1, TimeUnit.SECONDS)) { // Threads are still running System.out.println("Thread is still running"); } // All threads are completed System.out.println("\nThread completed it execution and terminated successfully\n"); } 

My questions What is the best practice for invoking a thread in parallel programming?
What will be the result (of the problem), after all, when will I use the first or second?
Note I ran into a problem with the first scenario when the program gets a hang every few days. So this problem is related / expected when I use the first method.

Any good / helpful answer would be appreciated :) Thanks.

+6
source share
2 answers

There are no significant differences in the two scenarios you posted, other than controlling the end of a stream in Scenario2; you always create a new thread for every incoming request. If you want to use ThreadPool, my advice is not to create it for each request, but to create it for each server and reuse threads. Sort of:

 public class YourClass { //in init method or constructor ExecutorService executor = Executors....;// choose from newCachedThreadPool() or newFixedThreadPool(int nThreads) or some custom option int clientNumber = 0; ServerSocket listener = new ServerSocket(port); while(true) { executor.execute(new GPSService(listener.accept(), client++, serverUrl)); } 

This will allow you to use the thread pool and control the number of threads used for your server. If you want to use Executor, this is the preferred way.

With a server pool, you need to decide how many threads are in the pool; you have different options, but you can start either with a fixed number or threads or with a pool that tries to use an idle thread, and if all threads are busy, it creates a new one ( newCachedThreadPool() ). The number of threads for distribution depends on many factors: the number of requests for approval and duration. The more your server code takes time, the more you need for extra thread. If your server-side code is very fast, there is a very good chance that the pool can reuse already allocated threads (since requests do not arrive completely at the same exact moment).

Say, for example, that you have 10 requests in a second, and each request lasts 0.2 seconds; if the request arrives at 0, 0.1, 0.2, 0.3, 0.4, 0.5, .. part two (for example, 23/06/2015 7: 16: 00: 00, 23/06 / 2015 7:16:00: 01, 06/23/2015 7: 16: 00: 02) you only need three threads, since a request starting with 0.3 can be executed by the thread on which the first request is executed (one of 0) etc. (The request at time 0.4 can reuse the stream used for the request, which came in 0.1). Ten requests are controlled by three threads.

I recommend that you (if you have not done so) read Java Concurrency in practice (completing the task - chapter 6); which is a great book on how to create a parallel Java application.

+3
source

From oracle documentation from Executors

 public static ExecutorService newCachedThreadPool() 

Creates a pool of threads, which if necessary creates new threads, but will use previously created threads when they are available. These pools typically improve the performance of programs that perform many short-lived asynchronous tasks.

Calls for execution will reuse previously created threads, if available. If an existing thread is not available, a new thread will be created and added to the pool. Themes that have not been used for sixty seconds are completed and removed from the cache.

Thus, a pool that remains idle for a long time will not consume any resources. Note that pools with similar properties, but different details (for example, timeout parameters) can be created using ThreadPoolExecutor constructors.

 public static ExecutorService newFixedThreadPool(int nThreads) 

Creates a thread pool that reuses a fixed number of threads working with a common unlimited queue. At any time, in most cases, nThreads will be active processing tasks. If additional tasks are dispatched when all threads are active, they will wait in a queue until a thread is available.

If any thread terminates due to a failure during execution before shutting down, a new one, if necessary, will take its place for subsequent tasks. Threads in the pool will exist until they are explicitly disabled.

@Giovanni says that you do not need to specify the number of threads in newCachedThreadPool , unlike newFixedThreadPool (), where you need to pass the maximum maximum length of the number of threads to ThreadPool.

But between the two, newFixedThreadPool() is preferred. newCachedThread Pool can cause a leak, and you can reach the maximum number of available threads due to unlimited nature. Some consider it evil.

Take a look at the related SE question:

Why is an ExecutorService created using newCachedThreadPool evil?

+1
source

Source: https://habr.com/ru/post/989441/


All Articles