JAVA 线程池 使用场景与异常处理

介绍

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

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

//方式二
((Runnable) () ->  dosomething()).run();
      
一、几种常用的线程池
  1. newSingleThreadExecutor
    创建一个单线程的线程池。这个线程池只有一个线程在工作,也就是相当于单线程串行执行所有任务。如果这个唯一的线程因为异常结束,那么会有一个新的线程来替代它。此线程池保证所有任务的执行顺序按照任务的提交顺序执行。

    ExecutorService service = Executors.newSingleThreadExecutor();
    service .execute(() -> {
    				try{
    					dosomething();
      			    }catch(Exception e){
    					log.error(e);
    				}
    });
    
  2. newFixedThreadPool
    创建固定大小的线程池。每次提交一个任务就创建一个线程,直到线程达到线程池的最大大小。线程池的大小一旦达到最大值就会保持不变,如果某个线程因为执行异常而结束,那么线程池会补充一个新线程。

    
    ExecutorService service = Executors.newFixedThreadPool(5);
    service.execute(() -> {
    				try{
    					dosomething();
      			    }catch(Exception e){
    					log.error(e);
    				}
    });
    
  3. newCachedThreadPool
    创建一个可缓存的线程池。如果线程池的大小超过了处理任务所需要的线程,
    那么就会回收部分空闲(60秒不执行任务)的线程,当任务数增加时,此线程池又可以智能的添加新线程来处理任务。此线程池不会对线程池大小做限制,线程池大小完全依赖于操作系统(或者说JVM)能够创建的最大线程大小。

    	ExecutorService service = Executors.newCachedThreadPool();
    		service.execute(() -> {
    				try{
    					dosomething();
      			    }catch(Exception e){
    					log.error(e);
    				}
    });
    
  4. 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();释放锁

java讨论群:931243010 密码 11111111

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值