介绍

单个线程使用完随即被销毁,如果在list中频繁创建、销毁线程,会给服务器带来不小的性能开支,所有使用线程池将线程的创建、销毁工作统一处理,最后销毁,以此来提高效率 。

//普通创建线程方式一
new Thread(() -> {
                dosomething();
            }).start();

//方式二
((Runnable) () ->  dosomething()).run();

一、几种常用的线程池

  1. newSingleThreadExecutor
    创建一个单线程的线程池。这个线程池只有一个线程在工作,也就是相当于单线程串行执行所有任务。如果这个唯一的线程因为异常结束,那么会有一个新的线程来替代它。此线程池保证所有任务的执行顺序按照任务的提交顺序执行。
ExecutorService service = Executors.newSingleThreadExecutor();
service .execute(() -> {
				try{
					dosomething();
  			    }catch(Exception e){
					log.error(e);
				}
});
  1. newFixedThreadPool
    创建固定大小的线程池。每次提交一个任务就创建一个线程,直到线程达到线程池的最大大小。线程池的大小一旦达到最大值就会保持不变,如果某个线程因为执行异常而结束,那么线程池会补充一个新线程。
ExecutorService service = Executors.newFixedThreadPool(5);
service.execute(() -> {
				try{
					dosomething();
  			    }catch(Exception e){
					log.error(e);
				}
});
  1. newCachedThreadPool
    创建一个可缓存的线程池。如果线程池的大小超过了处理任务所需要的线程,
    那么就会回收部分空闲(60秒不执行任务)的线程,当任务数增加时,此线程池又可以智能的添加新线程来处理任务。此线程池不会对线程池大小做限制,线程池大小完全依赖于操作系统(或者说JVM)能够创建的最大线程大小。
ExecutorService service = Executors.newCachedThreadPool();
		service.execute(() -> {
				try{
					dosomething();
  			    }catch(Exception e){
					log.error(e);
				}
});
  1. newScheduledThreadPool
    创建一个大小无限的线程池。此线程池支持定时以及周期性执行任务的需求。
ExecutorService service = Executors.newScheduledThreadPool(2);

    long initialDelay1 = 1;
    long period1 = 1;
    // 从现在开始1秒钟之后,每隔1秒钟执行一次job1
    ((ScheduledExecutorService) service).scheduleAtFixedRate(
            new Thread(() -> {
            }), initialDelay1,
            period1, TimeUnit.SECONDS);

    long initialDelay2 = 1;
    long delay2 = 1;
    // 从现在开始2秒钟之后,每隔2秒钟执行一次job2
    ((ScheduledExecutorService) service).scheduleWithFixedDelay(
            new Thread(() -> {
            }), initialDelay2,
            delay2, TimeUnit.SECONDS);

二、 @Async

该注解标注该方法或类是一个异步的方法

注意 该注解在同一类中使用不会生效

@EnableAsync //启动类注解
@SpringBootApplication
public class ManageApplication {
		....
}	

@Component  //交给spring处理初始化该类
public class Jobs {
 	@Async
    public void tes12() {
        System.out.println("tes12");
    }
}


@Component
public class JobTest{
	@Autowired
  	Jobs dj;
  	
	public void excute() {
         dj.tes12(); //异步执行
	}

}

线程中出现异常 外部的try是捕获不到异常的(一个线程一个工作空间 互不干扰)
如:

try {
            new Thread(() -> {
                System.out.println(1 / 0);
            }).start();
            System.out.println("succ");
        } catch (Exception e) {
            System.out.println(e+"Thread"); //此条语句不会输出
        }

解决方案

//1、实现 UncaughtExceptionHandler 重写uncaughtException方法
	class MyUncaughtExceptionhandler implements Thread.UncaughtExceptionHandler {

    /**
     * 捕获异常 线程当中出现的异常 将在这里捕获
     */
    @Override
    public void uncaughtException(Thread t, Throwable e) {
        System.out.println("caught  " + e);
    }

	//2、在线程中try	
	new Thread(() -> {
		try{
              System.out.println(1 / 0);
              } catch (Exception e) {
          	System.out.println(e+"Thread");
     			 }
          }).start();

submit =>有返回值future对象
execute => 无返回值

lock.lock();获得锁 如果线程拿到锁,将会一直等待
lock.unlock();释放锁

lock.trylock(5,TimeUnit.SECONDS);
尝试获得锁,如果获取不到将返回false 不会等待执行(可以设置时间) lock.unlock();释放锁