Java 多线程总结

本文深入探讨了线程池的使用原因、参数配置及执行规则,解释了如何通过线程池提高系统效率,避免频繁的线程创建与销毁。同时,文章详细介绍了线程池中的核心线程与非核心线程的行为,以及不同任务队列如SynchronousQueue和LinkedBlockingQueue的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.为什么用线程池:

        有时候,系统需要处理非常多的指定时间很短的请求,如果每个请求都开启一个新线程,系统就不断增加线程的创建和销毁,有时花在创建和销毁线程上的时间就会比线程执行的时间还长。

        而且当线程数量太多,系统不一定能受得了

        使用线程池主要为了解决以下问题:

              重用线程池中的线程,来减少线程的创建和销毁, 一次创建多次使用。

              对线程的维护和管理,比如定时开始,周期执行,并发数量控制

2.线程池参数

  • corePoolSize: 核心线程数,默认情况下核心线程一直存活,即使处于闲置壮体啊也不会受到KeepAliveTime限制,除非将allowCoreThread设置为true
  • maximumPoolSize:最大线程数,超过这个数量的线程会被阻塞,当任务队列没有设置大小的LinkedBlockingQueue时,这个值
  • keepAliveTime:闲置线程存活时间(不包含核心线程),非核心线程的闲置超时时间,
  • TimeUnit:时间单位
  • workQueue:线程队列 常用队列 SynchronousQueue(同步队列),LinkedBlockingQueue,ArrayBlockingQueue
  • threadFactory(): 线程工厂创建线程的方法
  • new AbortPolicy() 队列已满,而且当前线程数量已经超过最大线程数量的异常处理

3.线程池中的threadpoolexector,每个参数是干嘛用的 

        

4.线程池内部使用规则 

        线程池的线程执行规则跟任务队列有很大的关系:

        下面都是假设任务队列没有大小限制:

        1.如果线程数量<=线程核心数量,那么启动一个核心线程来执行任务,不会放入队列

        2.如果线程数量>核心线程数,但<=最大线程数,并且任务队列是LinkedBlockingQueue的时候,超过核心线程数量的任务会放到队列中

        3.如果线程数量>核心线程数,但<=最大线程数,并且任务队列是SynchononsQueue的时候,线程池会创建新的线程执行任务,也不会放到队列中,这些线程属于非核心线程,在任务完成后,闲置的时间达到了超过了时间就会被清除

        4.如果线程数量>核心线程,并且>最大线程数量,并且任务队列是LinkedBlockingQueue的时候 将超过核心线程的任务放在队列中也就是LinkedBlockingQueue 没有大小闲置时,线程池的最大线程数设置是无效的,他的想成数量不回超过核心线程数

        5.如果线程数量>核心线程,并且>最大线程数, 并且任务队列是SynchononsQueue的时候会应为线程拒绝添加而抛出异常

        6.当LinkedBlockingQueue塞满时,新的任务会直接创建新的线程来执行,当创建的线程数量超过最大数量的时候会抛出异常

        7.SyncchronousQueue没有数量限制,应为他根本不保留任务,直接交给线程池去执行,当任务超过最大线程数会直接抛出异常

5.有用过AtomicInteger吗?怎么用?

        AtomicInteger 是 int 的原子操作,保证线程安全。

6.用过ThreadLocal吗?怎么用的? JDK1.2提供

7.程序、进程、线程的区别是什么? 

        程序:是一个指令的集合,程序不能独立执行,,只有被加载到内存中,系统为他分配资源之后才能执行

        进程:一个执行的程序称为进程,进程好似系统分配资源的独立单位,每个进程都真有特定的地址空间,程序是进程的静态文本,进程是程序在系统内顺序执行的动态活动

         线程:是进程的单一的连续控制流程,线程是cpu调度和分配的基本单位,是比进程更小的能独立运行的基本单位,也称为轻量级进程,线程不能独立存在,必须依附于某个进程,一个进程可以包含多个并行的线程,一个线程肯定属于一个进程,java虚拟机允许并发执行多个线程

8.Java中创建线程的方式

  •   继承Thread类
  • 实现Runnable接口
  • 实现Callable、FutureTask包装器创建Thread线程
  • 使用ExecutorService、callable、Future 实现又返回结果的线程

9.说说sleep 、yield 、join 、wait 区别:

    sleep:方法需指定等待的时间,它可以让当前正在执行的线程在制定的时间内暂停执行,进入阻塞状态,该方法可以让其他优先级或者高优先级的线程得到执行的机会,也可以让低优先级的线程得到执行机会,但是sleep 不是释放“锁标志”也就说有synchronized同步块,其他线程仍让不能访问共享数据 ,用于线程

  • Thread.sleep()方法用来暂停线程的执行, 将cpu放飞线程调度器
  • Thread.sleep()方法是一个静态的方法,它暂停的是当前执行的线程
  • Java有两种sleep方法,一个是毫秒的参数,一个是有毫秒和纳秒两个参数
  • 与wait 不同sleep不回释放锁
  • 如果其他线程终端了一个休眠的线程,sleep 会抛出异常 InterruptedException
  • 休眠的线程在唤醒之后不保证能获取到cpu,他会先进入就绪状态,与其他线程竞争cpu
  • 一个易错的地方,当调用sleep()方法后会暂停线程t,这事不对的,因为Thead.sleep()方法是一个静态方法,他会使当前线程 而不是t线程进入休眠状态

     join:当前线程调用此方法的线程执行结束后在继续执行,join方法必须在线程start 之后调用才有意义

    yield:它仅仅释放线程所占用的CPU资源,从而让其他线程有机会运行,但是并不能保证摸个特定的线程能够获取CPU资源,谁能获取cpu资源完全取决于调度器,在有些情况下调用yield方法的线程甚至会再次获取CPU资源,所以依赖yield的方法是不可靠的,它只能尽力而为,作用与线程

    wait():

  •   wait只能同步(synchronized)环境中被调用,而sleep不需要
  • 进入wait 状态的线程能够被 notify 和 notifyall 唤醒, 范式进入sleep 的线程是不能的
  • wait通常有条件的去执行,线程会一直处于wait状态,直到某个条件变为真。但是sleep 仅仅让你线程进入睡眠状态
  • wait方法在进入wait状态的时候会释放锁对象,但是sleep不会

wait 方法是针对一个被同步代码块加锁的对象

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值