JAVA拾遗系列之JAVA基础-多线程

原创
01/19 10:41
阅读数 31

一、概述

    要了解多线程,需要了解相关的基础知识。

    在计算机操作系统中,进程管理也称为处理机管理,其核心是如何合理地分配处理机的时间,提高系统的效率。在计算机系统中有多个并发执行的程序,采用程序这个静态概念已经不能描述程序执行时动态变化的过程,所以引入了进程。

    进程是程序的一次执行。进程通常由程序、数据和进程控制块组成。进程的三态模型指的是运行、就绪、阻塞,进程的五态模型指的是新建、就绪、运行、阻塞、终止。

    由于进程的创建、撤销和切换中,系统必须为之付出较大的时空开销,因此在系统中设置的进程数目不宜过多,进程切换的频率不宜太高,这就限制了并发程序的提高。引入线程后,将传统进程的两个基本属性分开,线程作为调度和分配的基本单位,进程作为独立分配资源的单位。线程基本上不拥有资源,只拥有一点运行时必不可少的资源(如程序计数器、一组寄存器和栈)。

二、JAVA线程池

    合理使用线程池有利于提高线程的复用性,从而提高系统的运行效率。Java提供ThreadPoolExecutor来创建不同场景下的线程池,主要分为四类:

        1、newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
        2、newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
        3、newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。
        4、newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。

    无论创建哪种线程池,都有同样的参数,主要是:

        1、corePoolSize,核心线程数,也就是同时运行的线程数

        2、maximumPoolSize,最大容纳的线程数量,超过数量之后,有几种策略,详见handler参数

        3、keepAliveTime,线程的生命时长

        4、unit,与keepAliveTime对应代表时间的单位

        5、workQueue,队列

        6、handler,提交线程数量大于maximumPoolSize时的处理器,有四种处理方式:1、AbortPolicy,抛出异常给调用者;2、CallerRunsPolicy,在调用者所在线程执行;3、DiscardOldestPolicy,抛弃等待队列中等待最长的那个任务,并把这个任务加入到队列;4、DiscardPolicy,抛弃任务。

        7、threadFactory,线程创建工厂

    ThreadPoolExecutor有几个核心的方法:

        1、execute:执行任务

        2、getCorePoolSize:获取普通运行时线程数量上限

        3、getPoolSize:获取当前线程池数量

        4、getQueue:获取等待队列

        5、getActiveCount:获取正在执行的线程数量(估计值)

三、JAVA线程锁

    当对数据修改时,如果两个线程同时去修改同一条数据,这样产生的结果就不是我们预期的结果。这时候就需要对修改操作进行加锁,让jvm里同一时刻只能有一个线程能够执行修改方法。在Java中,java.util.concurrent.locks包下的ReentrantLock可以很方便的实现加锁和释放锁。示例代码如下:

class X {
   private final ReentrantLock lock = new ReentrantLock();
   // ...

   public void m() { 
     lock.lock();  // block until condition holds
     try {
       // ... method body
     } finally {
       lock.unlock()
     }
   }
 }

四、分布式锁基本思路

    当在微服务中,同一个服务可能部署多个示例,这样同样的代码加锁就变得没有任何意义。所以引入了分布式锁,分布式锁核心原理是借助第三方中间件,如Reids,存储一个标识:

        1、当执行加锁代码时,检查是否存在标识;

        2、如果存在,表示其它线程正在执行;

        3、如果不存在表示没有线程正在执行,可以进行加锁。

有兴趣的大佬大神可以关注下小弟的微信公共号,一起学习交流,扫描以下二维码关注即可。

展开阅读全文
加载中

作者的其它热门文章

打赏
0
0 收藏
分享
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部