The use of the Executors class to create and manage threads in Java concurrent programming

  • 2020-05-07 19:34:24
  • OfStack

Executors 1 class
The
Executors class can be considered a "utility class." To quote from JDK1.6 API:
  factory and utility methods for the Executor, ExecutorService, ScheduledExecutorService, ThreadFactory, and Callable classes defined in this package. This class supports the following methods:
(1) create and return a method that sets ExecutorService with a commonly used configuration string.
(2) creates and returns a method that sets ScheduledExecutorService with a commonly used configuration string.
(3) creates and returns the "wrapped" ExecutorService method, which disables reconfiguration by making implementation-specific methods inaccessible.
(4) creates and returns an ThreadFactory method that sets the newly created thread to a known state.
(5) a method that creates and returns Callable in non-closure form so that it can be used in execution methods that require Callable.
      gets instances of multiple thread pools through this class, such as newSingleThreadExecutor() for single-threaded ExecutorService, newFixedThreadPool() for fixed-size thread pools ExecutorService, and so on. There are a lot of things you can do with ExecutorService, the easiest is to use it to execute Runnable objects, and you can also execute 1 to implement Callable < T > The object. start() method of Thread has no return value. If the method executed by this thread has a return value, ExecutorService is better. You can choose submit(), invokeAll() or invokeAny(), and choose the appropriate method according to the specific situation.
Some of the methods provided in this class are:
1.1 public static ExecutorService newCachedThreadPool()
creates a thread pool that creates new threads as needed, but reuses previously constructed threads when they are available. For programs that perform many short-term asynchronous tasks, these thread pools typically improve program performance.
 
1.2 public static ExecutorService newFixedThreadPool(int nThreads)
creates a pool of threads with a fixed number of threads that can be reused to run the threads in a Shared unbounded queue.
 
1.3 public static ExecutorService newSingleThreadExecutor()
creates an Executor using a single worker thread to run the thread in an unbounded queue.
 
All three methods can be used together with an instance of interface ThreadFactory. And returns an instance of the ExecutorService interface.
2. Interface ThreadFactory
creates objects for new threads as needed. Using a thread factory eliminates the need to manually write calls to new Thread, allowing applications to use special thread subclasses, properties, and so on.
The simplest implementation of this interface is:


class SimpleThreadFactory implements ThreadFactory {
  public Thread newThread(Runnable r) {
   return new Thread(r);
  }
 }

3. Interface ExecutorService
provides a way to manage terminations.
4. Create a standard thread pool to start threads
4.1 provides a simple thread that implements the Runnable interface
MyThread.java


package com.zj.concurrency.executors;
 
public class MyThread implements Runnable {
  private int count = 1, number;
 
  public MyThread(int num) {
    number = num;
    System.out.println("Create Thread-" + number);
  }
 
  public void run() {
    while (true) {
      System.out.println("Thread-" + number + " run " + count+" time(s)");
      if (++count == 3)
       return;
    }
  }
}

This thread prints out the corresponding creation and execution information.
 
4.2 starts threads with CachedThreadPool
CachedThreadPool.java


package com.zj.concurrency.executors;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
 
public class CachedThreadPool {
  public static void main(String[] args) {
    ExecutorService exec = Executors.newCachedThreadPool();
    for (int i = 0; i < 5; i++)
      exec.execute(new MyThread(i));
    exec.shutdown();
  }
}

Results:


Create Thread-0
Create Thread-1
Create Thread-2
Create Thread-3
Thread-0 run 1 time(s)
Thread-0 run 2 time(s)
Thread-1 run 1 time(s)
Thread-1 run 2 time(s)
Thread-2 run 1 time(s)
Thread-2 run 2 time(s)
Create Thread-4
Thread-4 run 1 time(s)
Thread-4 run 2 time(s)
Thread-3 run 1 time(s)
Thread-3 run 2 time(s)

 
4.3 starts the thread using FixedThreadPool


FixedThreadPool.java
package com.zj.concurrency.executors;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
 
public class FixedThreadPool {
  public static void main(String[] args) {
    ExecutorService exec = Executors.newFixedThreadPool(2);
    for (int i = 0; i < 5; i++)
      exec.execute(new MyThread(i));
    exec.shutdown();
  }
}

Results:


Create Thread-0
Create Thread-1
Create Thread-2
Create Thread-3
Create Thread-4
Thread-0 run 1 time(s)
Thread-0 run 2 time(s)
Thread-2 run 1 time(s)
Thread-2 run 2 time(s)
Thread-3 run 1 time(s)
Thread-3 run 2 time(s)
Thread-4 run 1 time(s)
Thread-4 run 2 time(s)
Thread-1 run 1 time(s)
Thread-1 run 2 time(s)

 
4.4 start the thread using SingleThreadExecutor
SingleThreadExecutor.java


package com.zj.concurrency.executors;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
 
public class SingleThreadExecutor {
  public static void main(String[] args) {
    ExecutorService exec = Executors.newSingleThreadExecutor();
    for (int i = 0; i < 5; i++)
      exec.execute(new MyThread(i));
    exec.shutdown();
  }
}

Results:


Create Thread-0
Create Thread-1
Create Thread-2
Create Thread-3
Create Thread-4
Thread-0 run 1 time(s)
Thread-0 run 2 time(s)
Thread-1 run 1 time(s)
Thread-1 run 2 time(s)
Thread-2 run 1 time(s)
Thread-2 run 2 time(s)
Thread-3 run 1 time(s)
Thread-3 run 2 time(s)
Thread-4 run 1 time(s)
Thread-4 run 2 time(s)

5. Use with ThreadFactory interface
we tried to add daemon and priority property Settings to the thread.
5.1 sets the background thread properties
DaemonThreadFactory.java


package com.zj.concurrency.executors.factory;
import java.util.concurrent.ThreadFactory;
 
public class DaemonThreadFactory implements ThreadFactory {
  public Thread newThread(Runnable r) {
    Thread t = new Thread(r);
    t.setDaemon(true);
    return t;
  }
}

 
5.2 sets the priority properties
highest priority MaxPriorityThreadFactory.java


package com.zj.concurrency.executors.factory;
import java.util.concurrent.ThreadFactory;
 
public class MaxPriorityThreadFactory implements ThreadFactory {
  public Thread newThread(Runnable r) {
    Thread t = new Thread(r);
    t.setPriority(Thread.MAX_PRIORITY);
    return t;
  }
}

Lowest priority MinPriorityThreadFactory.java


package com.zj.concurrency.executors;
 
public class MyThread implements Runnable {
  private int count = 1, number;
 
  public MyThread(int num) {
    number = num;
    System.out.println("Create Thread-" + number);
  }
 
  public void run() {
    while (true) {
      System.out.println("Thread-" + number + " run " + count+" time(s)");
      if (++count == 3)
       return;
    }
  }
}
0

 
5.3 start the thread with property Settings
ExecFromFactory.java


package com.zj.concurrency.executors;
 
public class MyThread implements Runnable {
  private int count = 1, number;
 
  public MyThread(int num) {
    number = num;
    System.out.println("Create Thread-" + number);
  }
 
  public void run() {
    while (true) {
      System.out.println("Thread-" + number + " run " + count+" time(s)");
      if (++count == 3)
       return;
    }
  }
}
1

Results:


package com.zj.concurrency.executors;
 
public class MyThread implements Runnable {
  private int count = 1, number;
 
  public MyThread(int num) {
    number = num;
    System.out.println("Create Thread-" + number);
  }
 
  public void run() {
    while (true) {
      System.out.println("Thread-" + number + " run " + count+" time(s)");
      if (++count == 3)
       return;
    }
  }
}
2


Related articles: