从 电商系统 角度全方位 研究+吃透“Java多线程”(上篇)

本文从电商系统的角度深入探讨Java多线程,涵盖线程池的基础理论、JUC线程池的工作机制、锁的分类及其应用,以及原子操作的原理。通过案例分析,阐述了线程池如何优化资源消耗和响应速度,以及锁在并发控制中的角色,如ReentrantLock和ConcurrentHashMap。最后,讨论了原子操作在确保并发安全中的作用。
摘要由CSDN通过智能技术生成

推荐学习

01 前言

本章节主要分享下,多线程并发在电商系统下的应用。主要从以下几个方面深入:线程相关的基础理论和工具、多线程程序下的性能调优和电商场景下多线程的使用。

02 多线程

2.1 JU·C线程池

(1)概念

回顾线程创建的方式

  • 继承Thread
  • 实现Runnable
  • 使用FutureTask

线程状态

NEW:刚刚创建,没做任何操作

RUNNABLE:调用run,可以执行,但不代表一定在执行(RUNNING,READY)

WATING:使用了waite(),join()等方法

TIMED_WATING:使用了sleep(long),wait(long),join(long)等方法

BLOCKED:抢不到锁

TERMINATED:终止

线程池基本概念

根据上面的状态,普通线程执行完,就会进入TERMINA TED销毁掉,而线程池就是创建一个缓冲池存放线程,执行结束以后,该线程并不会死亡,而是再次返回线程池中成为空闲状态,等候下次任务来临,这使得线程池比手动创建线程有着更多的优势:

  • 降低系统资源消耗,通过重用已存在的线程,降低线程创建和销毁造成的消耗;
  • 提高系统响应速度,当有任务到达时,通过复用已存在的线程,无需等待新线程的创建便能立即执行;
  • 方便线程并发数的管控。因为线程若是无限制的创建,可能会导致内存占用过多而产生OOM
  • 节省cpu切换线程的时间成本(需要保持当前执行线程的现场,并恢复要执行线程的现场)。
  • 提供更强大的功能,延时定时线程池。(Timer vs ScheduledThreadPoolExecutor)

常用线程池类结构

说明:

  • 最常用的是ThreadPoolExecutor
  • 调度用的ScheduledThreadPoolExecutor
  • Executors是工具类,协助创建线程池

(2)工作机制

在线程池的编程模式下,任务是提交给整个线程池,而不是直接提交给某个线程,线程池在拿到任务后,就在内部寻找是否有空闲的线程,如果有,则将任务交给某个空闲的线程。一个线程同时只能执行一个任务,但可以同时向一个线程池提交多个任务。

线程池状态

  • RUNNING:初始化状态是RUNNING。线程池被一旦被创建,就处于RUNNING状态,并且线程池中的任务数为0。RUNNING状态下,能够接收新任务,以及对已添加的任务进行处理。
  • SHUTDOWN:SHUTDOWN状态时,不接收新任务,但能处理已添加的任务。调用线程池的shutdown()接口时,线程池由RUNNING -> SHUTDOWN。
//shutdown后不接受新任务,但是task1,仍然可以执行完成
ExecutorService poolExecutor = Executors.newFixedThreadPool(5);
poolExecutor.execute(new Runnable() {
   public void run() {
       try {
           Thread.sleep(1000);
           System.out.println("finish task 1");
       } catch (InterruptedException e) {
           e.printStackTrace();
       }
   }
});
poolExecutor.shutdown();
poolExecutor.execute(new Runnable() {
   public void run() {
       try {
           Thread.sleep(1000);
       } catch (InterruptedException e) {
           e.printStackTrace();
       }
   }
});
System.out.println("ok");
  • STOP:不接收新任务,不处理已添加的任务,并且会中断正在处理的任务。调用线程池的shutdownNow()接口时,线程池由(RUNNING 或SHUTDOWN ) -> STOP
//改为shutdownNow后,任务立马终止,sleep被打断,新任务无法提交,task1停止
poolExecutor.shutdownNow();
  • TIDYING:所有的任务已终止,ctl记录的”任务数量”为0,线程池会变为TIDYING。线程池变为TIDYING状态时,会执行钩子函数terminated(),可以通过重载terminated()函数来实现自定义行为
//自定义类,重写terminated方法
public class MyExecutorService extends ThreadPoolExecutor {
   public MyExecutorService(int corePoolSize, int maximumPoolSize, long
keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {
       super(corePoolSize, maximumPoolSize, keepAliveTime, unit,
workQueue);
   }
   @Override
   protected void terminated() {
       super.terminated();
       System.out.println("treminated");
   }
   
   //调用 shutdownNow, ternimated方法被调用打印
   public static void main(String[] args) throws InterruptedException {
       MyExecutorService service = new
MyExecutorService(1,2,10000,TimeUnit.SECONDS,new
LinkedBlockingQueue<Runnable>(5));
       service.shutdownNow();
   }
}
  • TERMINA TED:线程池处在TIDYING状态时,执行完terminated()之后,就会由TIDYING ->TERMINA TED

(3)结

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值