Create a thread in java way

Create a thread way:

  • Inheritance thread
  • Implement runnable
  • Thread Pool
  • FurureTask/Callable

The first: Inheritance thread

demo1:

public class demo1 {
    public static void main(String[] args) {
        new MyThread().start();

    }
}
class MyThread extends Thread{

    public void run(){
        System.out.println("线程创建");
    }
}

 

The second: to achieve runnable

demo2:

public class demo2 {
    public static void main(String[] args) {
        new Thread(new MyThreadRun()).start();

    }
}

class MyThreadRun implements Runnable{
    @Override
    public void run() {
        System.out.println("线程创建");
    }
}

When using runnable interface implementation, we generally use the form of an anonymous class:

public class demo2 {
    public static void main(String[] args) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("线程创建");
            }
        }).start();
    }
}

Because Runnable is a function interface, so you can use lambda expressions to write:

public class demo2 {
    public static void main(String[] args) {
     new Thread(()->{ 
         System.out.println("线程创建");
     }).start();
    }
}

 

Third: using a thread pool:

First, look at the advantages of the thread pool :
thread pool to do the job as long as control the number of threads running, the task will be placed in the queue process, and then start these tasks after thread creation, if the number of threads exceeds the maximum number exceeds the number of thread waiting in line, and other thread is finished, then remove from the queue to perform the task.
Its main features are: thread multiplexing; maximum number of concurrent control; managing threads.
First: reduce resource consumption. By reusing the thread has been created to reduce thread creation and destruction caused by the consumption of a pin.
Second: improving the response speed. When the mission arrives, the task may not need to wait for thread creation can be implemented immediately.
Third: to improve the manageability of threads. A thread is a scarce resource, if the unlimited creation, not only will sell a waste of resources, but also reduce the stability of the system, using a thread pool can be unified distribution, tuning and monitoring.

Java threads in the pool is achieved by Executor framework, we used the Executor, Executors, ExecutorService, ThreadPoolExecutor these classes in the framework.

Executors There are three ways to create a thread pool:

// thread pool to create a fixed number of threads 
ExecutorService executorService1 = Executors.newFixedThreadPool (5 );
 // thread pool thread to create a 
ExecutorService executorService12 = Executors.newSingleThreadExecutor ();
 // thread pool threads to create expansion 
ExecutorService executorService13 = Executors. newCachedThreadPool ();

Let's look at their source code:

 public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }


 public static ExecutorService newSingleThreadExecutor() {
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>()));
    }

 public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }

You can see that they are ultimately call the same method new new ThreadPoolExecutor () , let us look at this constructor:

    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             Executors.defaultThreadFactory(), defaultHandler);
    }

You can see to create a thread pool need to pass in the seven parameters:

1, corePoolSize: Permanent core number of threads in the thread pool
2, maximumPoolSize: thread pool can accommodate the maximum number of execution threads, this value must be greater than or equal. 1
. 3, keepAliveTime: extra current thread pool idle thread survival time when the amount exceeds corePoolSize, when the idle time reaches keepAliveTime, excess threads will be destroyed until only so far corePoolSize threads
4, unit: keepAliveTime unit
task queue task was submitted but not yet executed: 5, workQueue
6, threadFactory : representation generation of worker threads in the thread pool thread factory used to create a thread, the general default to
rejecting strategy indicates when the queue is full, and the worker threads greater than the maximum number of threads equal to the thread pool (maximumPoolSize): 7, handler how to reject the request of runnable execution of strategy

 

Then we'll look back at these three methods to create a thread pool, incoming parameters of these meanings, here we have to look at BlockingQueue blocking queue , when you create expandable thread pool, blocking queue and the other two are not used same.

 

BlockingQueue

ArrayBlockingQueue: the array of structures bounded blocking queue.
LinkedBlockingQueue: a list structure consisting bounded (the default is size but Integer.MAX_VALUE) blocking queue.
PriorityBlockingQueue: Support prioritization of unbounded blocking queue.
DelayQueue: Use delayed unbounded priority queue implementation of blocking queue.
SynchronousQueue: blocking queue element is not stored, i.e. a single element queue.
LinkedTransferQueue: a list consisting of unbounded blocking queue.
LinkedBlockingDeque: a list composed of two-way blocking queue.

 Common methods:

 

 

 

 

handler: deny policy, the waiting queue is already full, never would fit new task at the same time, max threads in the pool reached, new tasks can not continue to serve, this time we need to reject the policy.

AbortPolicy (default): Direct RejectedExecutionException throws an exception that prevent normal
CallerRunsPolicy: "The caller is running" an adjustment mechanism, the policy will neither abandon the task, it will not throw an exception, but will fall back to certain tasks the caller, thereby reducing the flow of new tasks.
DiscardOldestPolicy: abandon the queue waiting for the longest task, the current task and then join the queue to try again submit the current job.
DiscardPolicy: This policy can not handle the task silently discarded, no treatment does not throw an exception. If you allow the task is missing, this is the best strategy.

Understanding of these parameters later, we know the advantages and disadvantages of the three ways to create a thread pool, but we generally do not go with them, instead of using a custom thread pool.

  ExecutorService executorService = new ThreadPoolExecutor(
                2,
                5,
                20,
                TimeUnit.SECONDS,
                new LinkedBlockingDeque<>(3),
                new ThreadPoolExecutor.CallerRunsPolicy());

We wrote a demo:

public  class ThreadPoolDemo { 

    public  static  void main (String [] args) {
        / * // create a fixed number of threads in the thread pool 
        ExecutorService executorService1 Executors.newFixedThreadPool = (. 5); 
        // Create a thread pool threads 
        ExecutorService executorService12 = Executors.newSingleThreadExecutor (); 
        // create a thread pool thread expansion 
        ExecutorService executorService13 = Executors.newCachedThreadPool (); * / 
        ExecutorService ExecutorService = new new ThreadPoolExecutor (
                 2 ,
                 5 ,
                 20 , 
                TimeUnit.SECONDS,
                new LinkedBlockingDeque<>(3),
                new ThreadPoolExecutor.CallerRunsPolicy());

         for (int i = 1; i < 10 ; i++) {
                     new Thread(()->{
                         executorService.execute(()->{
                             System.out.println(Thread.currentThread().getName()+"处理任务");
                         });
                     },""+i).start();
                 }
    }
}

 

Principle thread pool

1. After you create a thread pool, start waiting for the request.
2, when calling execute () method to add a task request, the thread pool will make a judgment as follows:
     2.1 If the number of threads running less than corePoolSize, then immediately create a thread to run this task;
    2.2 if the number of running threads is greater than or equal to corePoolSize, then this task in the queue;
    the number of threads 2.3 If the queue is full time and running is also less than maximumPoolSize, you still have to create a non-core thread to run this task immediately;
    the number of threads 2.4 If the queue is full and running greater than or equal to maximumPoolSize, then starts the thread pool to perform saturation deny policy.
3, when a thread is to complete the task, it is removed from a queue task is performed.
4, when a thread is nothing more than a certain period of time (keepAliveTime), the thread will determine:
      If the number of the currently running thread is more than corePoolSize, then the thread is stopped.
      So after all the tasks of the thread pool is completed, it will eventually shrink to the size of corePoolSize.
 

Fourth: FurureTask / Callable

FurureTask / Callable and Runnable like to use, let's take a look at the demo:

class CallAbleTest implements Callable{

    @Override
    public Integer call() throws Exception {

        return 1024;
    }
}
public class CallableDemo {

    public static void main(String[] args) throws ExecutionException, InterruptedException {

        CallAbleTest callAbleTest = new CallAbleTest();
        FutureTask<Integer> futureTask = new FutureTask<>(callAbleTest);
        new Thread(futureTask).start();

        Integer result = futureTask.get();

        System.out.println("reault"+result);

    
        new Thread(futureTask).start();
        System.out.println("result:"+futureTask.get());

    }
}

We write an implementation class that implements Callable interface and override its methods. We can see the difference and the Runnable:

     (1) whether there is a return value
        (2) is Throws
        (3) rewriting method is not the same, a RUN is, a call is

FurureTask / Callable provides a more powerful way for us.

Since Callable interface is a function, we can be like Runnable as a lambda expression written in the form of an anonymous inner class.

public class CallableDemo {

    public static void main(String[] args) throws ExecutionException, InterruptedException {

        FutureTask<Integer> futureTask = new FutureTask<Integer>(()->{
           return 1024;
        });
        new Thread(futureTask).start();
        System.out.println("result:"+futureTask.get());

    }
}

It should be noted that, to obtain the return value need to get through futureTask.get (), which is a blocking method, when all the threads task is not yet complete, it will be blocked to wait here. For example there are three threaded tasks,

5 seconds to perform a task, a 3 seconds 2 seconds, then the main thread will block for 5 seconds, wait for all threads to perform tasks end.

 

Another point is why the new new the Thread (a FutureTask,) .start (); can pass a a FutureTask, , we can look at new new the Thread () method,

 

 

 The only way related to Runnable, and then we should be able to guess futureTask should be Runnable implementation class, we look at the structure of their relationship, we can indeed see FutureTask implementation class.

 

 

 These are four methods to create a thread, there is an error, please correct me ^ - ^.

 

Guess you like

Origin www.cnblogs.com/tdyang/p/11919402.html