Use thread - Java multithreading

Create a thread

By implementing Runnable interface

class RunnableDemo implements Runnable {
    private String threadName;

    private RunnableDemo(String name) {
        this.threadName = name;
        System.out.println("creating thread:" + threadName);
    }

    @Override
    public void run() {
        System.out.println("Running " + threadName);

        try {
            for (int i = 0; i < 10; i++) {
                System.out.println("Thread:" + threadName + "," + i);
                Thread.sleep(50);
            }
        } catch (InterruptedException e) {
            System.out.println("Thread " + threadName + "interrupter");
        }
        System.out.println("Thread " + threadName + " exiting");
    }
    // run
    public static void main(String[] args) {
        RunnableDemo r = new RunnableDemo("MyThread");
        r.run();
    }
}
复制代码

Through inheritance Thread class itself

public class ThreadDemo extends Thread {
    @Override
    public void run() {
        System.out.println("thread" + Thread.currentThread().getId() + " running...");
    }
    // run 10 thread
    public static void main(String[] args) throws InterruptedException {
        ThreadDemo[] threadDemos = new ThreadDemo[10];
        for (int i = 0; i < threadDemos.length; i++) {
            threadDemos[i] = new ThreadDemo();
        }
        for (ThreadDemo threadDemo : threadDemos) {
            threadDemo.start();
        }
        // wait other thread complete
        for (ThreadDemo threadDemo : threadDemos) {
            threadDemo.join();
        }
        System.out.println("completing");
    }
}
复制代码

Callable achieved by creating a thread (the thread can return value processing)

By FutureTaskpacking Callableinstance, through the Threadpackage FutureTaskinstance, and then calling Threadthe start()method

public class CallableDemo implements Callable {
    @Override
    public String call() throws Exception {
        return "yo!";
    }

    @Test
    public void callUse() throws Exception {
        CallableDemo callableDemo = new CallableDemo();
        System.out.println(callableDemo.call());
    }

    @Test
    public void threadUse() throws ExecutionException, InterruptedException {
        FutureTask futureTask= new FutureTask<>(new CallableDemo());
        Thread thread=new Thread(futureTask);
        thread.start();
        System.out.println(futureTask.get());
    }
}
复制代码

FutureTask inheritance

Thread pool thread of execution

Create a thread pool

General to create a thread through the class ThreadPoolExecutor

ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(
                          int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue workQueue,
                          ThreadFactory threadFactory,
                          RejectedExecutionHandler handler
                          )
复制代码
Variable Description
  • The basic thread pool size corePoolSize

  • The maximum size of the thread pool maximumPoolSize

  • keepAliveTime idle thread (beyond the basic size of thread) survival time

  • unit idle thread survival time unit (milliseconds, seconds ...)

  • workQueue task queue, the task of submitting a blocking queue ( BlockingQueue). More: the Java multithreading - Detailed blocking queue

  • Create a policy threadFactory thread production workers, thread, there is the default implementation, you can monitor thread information through custom thread factory

  • handler saturation strategy, when the thread because the task queue is full, or a task that has been submitted to a closed thread handling

    • AbortPolicy suspend the policy, the default policy , the policy will throw an exception RejectExecutionException, the caller can write your own exception handling code

    • DiscardRunsPolicy abandon the strategy, quietly abandon the task, do not throw an exception

    • DiscardOldestPolicy abandon the longest mission strategy will work queue oldest (that is, the next to be executed) tasks abandoned. Priority queue will be the highest priority

    • CallerRunsPolicy caller execution policy, adding threads to add a work queue threads to execute

ps: the reference table constructor

Inheritance

Use the thread pool

Runable Interface
public static void main(String[] args) throws InterruptedException, ExecutionException {
        ExecutorService pool=Executors.newFixedThreadPool(2);
        pool.execute(() -> System.out.println("yo!"));
        pool.shutdown();
}
复制代码
Callable Interface

By calling the submit method

In ExecutorServicethe overloaded provided submit()a method of receiving either Runnableinstance can receiving Callableinstances. For achieving Callablethe interface classes, override the need call()methods, and only through ExecutorServicethe submit()way to start call()Method

public static void main(String[] args) throws InterruptedException, ExecutionException {
        ExecutorService pool=Executors.newFixedThreadPool(2);
        Future future=pool.submit(() -> {
            Thread.sleep(100);
            return "yo!";
        });
        System.out.println(future.get());
        pool.shutdown();
}
复制代码
Use delay tasks and periodic task

Definition: Delay task ( "task after execution of 100ms") duty cycle ( "every 10ms to perform a task.")

Use: The new ScheduledThreadPoolExector () Object

Demo:

public class ScheduleExecutorDemo implements Runnable {
    private String name;

    public ScheduleExecutorDemo(String name) {
        this.name = name;
    }

    @Override
    public void run() {
        System.out.println(name + " 运行");
    }

    public static void main(String[] args) throws InterruptedException {
        ScheduledExecutorService executorService1 = Executors.newScheduledThreadPool(2);
        // after 10s run
        executorService1.schedule(new ScheduleExecutorDemo("task1"), 10, TimeUnit.SECONDS);
        executorService1.shutdown();

        ScheduledExecutorService executorService2 = Executors.newScheduledThreadPool(2);
        // run per 1s
        executorService2.scheduleAtFixedRate(new ScheduleExecutorDemo("task1"), 
                0, 1, TimeUnit.SECONDS);
        // run per 2s
        executorService2.scheduleWithFixedDelay(new ScheduleExecutorDemo("task2"), 
                0, 2, TimeUnit.SECONDS);
    }
}
复制代码
Use tips

Source: Alibaba Java Development Manual

  • Thread resources must be provided by the thread pool is not allowed to explicitly create their own threads in the application.

    Description: The benefits of using the thread pool is to reduce the overhead in creating and destroying threads consumed time and system resources, to solve the problem of insufficient resources. If you do not use the thread pool, it may cause the system to create a large number of similar threads lead consumed or memory problem "excessive handover".

  • Executors thread pool are not allowed to create, but by ThreadPoolExecutor way, this approach allows the students to write more clearly thread pool operating rules, to avoid the risk of resource depletion.

    Description: Executors malpractice thread pool objects returned as follows:

    • FixedThreadPool and SingleThreadPool: request queue length allowed Integer.MAX_VALUE, may accumulate a large number of requests, thereby causing OOM.

    • CachedThreadPool and ScheduledThreadPool: allow the number of threads to create Integer.MAX_VALUE, may create a large number of threads, resulting OOM.

  • When the multi-threaded parallel processing timing task, when Timer running multiple TimeTask, as long as one does not catch exceptions thrown, other tasks will automatically terminate, use ScheduledExecutorService is not the problem.

Ref:

  1. JDK1.8.0 source

  2. Callable interfaces of Java multi-threaded and thread pool

  3. "Java Concurrency in combat."

  4. "Java multi-threaded programming practical guide (core papers)"

Guess you like

Origin juejin.im/post/5d03a51e51882571521114fe