First we need understand some concepts. Let’s go.
What is a thread pool ?
It is a manager thread type of objects, which is able to limit the number of threads in addition to making the reuse of the same.
What are the types pool that we can have ?
NewFixedThreadPool : it is a pool of connections that previously set the amount of threads that want to use. So, if for example we want to establish up to 4 threads, this number will never more than it and they will be reused.
NewCachedThreadPool : it is the connection pool that grows dynamically according to the requests. It is ideal when you do not know the exact number of how many threads we need. The cool of this pool is that it also decrease the number of threads available when a thread is idle for more than 60 seconds.
NewSingleThreadExecutor : it is a pool of connections that possess only a single thread.
Example:
Below you can see an example using it.
In this Example we have the following situation: We are creating a server socket that will communicate with its clients by TCP protocol. This communication is being made through the Java Socket class. We can call multiple clients to connect simultaneously to this server and send a protocol with a message.
Our Server :
public class SocketServer { public static void main(String[] args) throws IOException { System.out.println("---- Start Server ----"); ServerSocket server = new ServerSocket(12345); // here is the inicial port // Create how many threads will be necessary and manager it ExecutorService pool = Executors.newCachedThreadPool(); while (true) { // After the first connection the server will be use // a port for which client connect in our server, // other else, which socket. Socket socket = server.accept(); System.out.println("New client in the port: " + socket.getPort()); DistributorTasks distributorTasks = new DistributorTasks(socket); pool.execute(distributorTasks); } } }
Observations :
If we want limit the quantity of threads that we will have in our pool then :
// Create a pool with 4 threads
ExecutorService pool = Executors.newFixedThreadPool(4);
Our Client
public class SocketClient { public static void main(String[] args) throws Exception{ // Here we define the port : 12345 Socket socket = new Socket("localhost", 12345); System.out.println("Connected"); // The text msg PrintStream printStream = new PrintStream(socket.getOutputStream()); printStream.println("Test Socket"); // To use the keyboard Scanner keyboard = new Scanner(System.in); keyboard.nextLine();// wait enter to continue // To close every thing. printStream.close(); // close output keyboard.close(); // close keyboard socket.close(); // Close the conection } }
Our Executor:
public class DistributorTasks implements Runnable { private Socket socket; public DistributorTasks(Socket socket) { this.socket = socket; } @Override public void run() { System.out.println("Tasks will be distributed " + socket); try { // Take the stream sent for this sock Scanner scanner = new Scanner(socket.getInputStream()); while (scanner.hasNextLine()){ System.out.println( scanner.nextLine() ); } } catch (Exception e) { e.printStackTrace(); } } }
If you test this example you will see in our console log: