Three ways to create threads

Create and run threads

Method 1, use Thread directly

// 创建线程对象
Thread t = new Thread() {
public void run() {
    // 要执行的任务
   }
};
// 启动线程
t.start();

For example:

     // 构造方法的参数是给线程指定名字,推荐
        Thread t1 = new Thread("t1") {
            @Override
            // run 方法内实现了要执行的任务
            public void run() {
                log.debug("hello");
            }
        };
        t1.start();

Method 2, use Runnable with Thread

Separate [thread] from [task] (code to be executed)

  • Thread represents a thread
  • Runnable runnable tasks (code to be executed by the thread)
        Runnable runnable = new Runnable() {
            public void run() {
            // 要执行的任务
            }
        };
        // 创建线程对象
        Thread t = new Thread(runnable);
        // 启动线程
        t.start();

For example:

public class Test2 {
	public static void main(String[] args) {
		//创建线程任务
		Runnable r = () -> {
            //直接写方法体即可
			System.out.println("Runnable running");
			System.out.println("Hello Thread");
		};
		//将Runnable对象传给Thread
		Thread t = new Thread(r);
		//启动线程
		t.start();
	}
}

Method 3: Combining FutureTask with Thread

Use FutureTask to specify the return value type of the thread with generics (the run method of Runnable has no return value)

FutureTask can receive parameters of Callable type to handle the case of returning results

        // 创建任务对象
        FutureTask<Integer> task3 = new FutureTask<>(() -> {
            log.debug("hello");
            return 100;
        });
        // 参数1 是任务对象; 参数2 是线程名字,推荐
        new Thread(task3, "t3").start();
        // 主线程阻塞,同步等待 task 执行完毕的结果
        Integer result = task3.get();
        log.debug("结果是:{}", result);
public class Test3 {
	public static void main(String[] args) throws ExecutionException, InterruptedException {
        //需要传入一个Callable对象
		FutureTask<Integer> task = new FutureTask<Integer>(new Callable<Integer>() {
			@Override
			public Integer call() throws Exception {
				System.out.println("线程执行!");
				Thread.sleep(1000);
				return 100;
			}
		});

		Thread r1 = new Thread(task, "t2");
		r1.start();
		//获取线程中方法执行后的返回结果
		System.out.println(task.get());
	}
}

Method 4: Use thread pool such as Executor framework

Parameter introduction

    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) {
        if (corePoolSize < 0 ||
            maximumPoolSize <= 0 ||
            maximumPoolSize < corePoolSize ||
            keepAliveTime < 0)
            throw new IllegalArgumentException();
        if (workQueue == null || threadFactory == null || handler == null)
            throw new NullPointerException();
        this.acc = System.getSecurityManager() == null ?
                null :
                AccessController.getContext();
        this.corePoolSize = corePoolSize;
        this.maximumPoolSize = maximumPoolSize;
        this.workQueue = workQueue;
        this.keepAliveTime = unit.toNanos(keepAliveTime);
        this.threadFactory = threadFactory;
        this.handler = handler;
    }

* @param corePoolSize the number of threads to keep in the pool, even * if they are idle, unless {@code allowCoreThreadTimeOut} is set

The number of threads kept in the pool will not be released even if the threads are idle. unless allowCoreThreadTimeOut is set *

@param maximumPoolSize the maximum number of threads to allow in the * pool

The maximum number of threads allowed in the pool

* @param keepAliveTime when the number of threads is greater than * the core, this is the maximum time that excess idle threads * will wait for new tasks before terminating.

When the number of threads is greater than the number of core threads, the thread will be terminated and released after the maximum time without receiving new tasks, and the final thread pool will be maintained at the size of corePoolSize

* @param unit the time unit for the {@code keepAliveTime} argument

time unit

* @param workQueue the queue to use for holding tasks before they are* executed. This queue will hold only the {@code Runnable} * tasks submitted by the {@code execute} method.

Blocking queue, used to store tasks waiting to be executed, if the current demand for threads exceeds corePoolSize

size, it will be placed here to wait for the idle thread to execute.

* @param threadFactory the factory to use when the executor * creates a new thread

Create a thread factory, such as specifying the thread name, etc.

* @param handler the handler to use when execution is blocked * because the thread bounds and queue capacities are reached

Rejection strategy, if the thread is full, the thread pool will use the rejection strategy

Operating principle: 

1. Create a thread pool, prepare core threads with the number of cores, and prepare to accept tasks

2. A new task comes in and is executed with the idle thread prepared by the core.

(1) When the core is full, put the incoming tasks into the blocking queue. The idle core will block the queue to obtain task execution by itself

(2) When the blocking queue is full, a new thread will be opened directly for execution, and the maximum number can only be opened to the number specified by max

(3) and max are executed. The idle threads with the Max-core number will be automatically destroyed after the time specified by keepAliveTime. Finally keep to the core size

(4) If the number of threads reaches the max number and new tasks come in, the rejection strategy specified by reject will be used for processing

3. All thread creation is created by the specified factory.

Guess you like

Origin blog.csdn.net/m0_62436868/article/details/131172862