Java多线程基本概念

多核的机器,现在已经非常常见了。即使是一块手机,也都配备了强劲的多核处理器。通过多进程和多线程的手段,就可以让多个CPU同时工作,来加快任务的执行。

多线程,是编程中一个比较高级的话题。由于它涉及到共享资源的操作,所以在编码时非常容易出现问题。Java的concurrent包,提供了非常多的工具,来帮助我们简化这些变量的同步,但学习应用之路依然充满了曲折。

本篇文章,将简单的介绍一下Java中多线程的基本知识。然后着重介绍一下初学者在多线程编程中一些最容易出现问题的地方,很多都是血泪经验。规避了这些坑,就相当于规避了90%凶残的多线程bug。

1. 多线程基本概念

1.1 轻量级进程

在JVM中,一个线程,其实是一个轻量级进程(LWP)。所谓的轻量级进程,其实是用户进程调用系统内核,所提供的一套接口。实际上,它还要调用更加底层的内核线程(KLT)。

实际上,JVM的线程创建销毁以及调度等,都是依赖于操作系统的。如果你看一下Thread类里面的多个函数,你会发现很多都是native的,直接调用了底层操作系统的函数。

下图是JVM在Linux上简单的线程模型。

image.png

可以看到,不同的线程在进行切换的时候,会频繁在用户态和内核态进行状态转换。这种切换的代价是比较大的,也就是我们平常所说的上下文切换(Context Switch)。

1.2 JMM

在介绍线程同步之前,我们有必要介绍一个新的名词,那就是JVM的内存模型JMM。

JMM并不是说堆、metaspace这种内存的划分,它是一个完全不同的概念,指的是与线程相关的Java运行时线程内存模型。

由于Java代码在执行的时候,很多指令都不是原子的,如果这些值的执行顺序发生了错位,就会获得不同的结果。比如,i++的动作就可以翻译成以下的字节码。

getfield      // Field value:I
iconst_1
iadd
putfield      // Field value:I

这还只是代码层面的。如果再加上CPU每核的各级缓存,这个执行过程会变得更加细腻。如果我们希望执行完i++之后,再执行i--,仅靠初级的字节码指令,是无法完成的。我们需要一些同步手段。

image.png

上图就是JMM的内存模型,它分为主存储器(Main Memory)和工作存储器(Working Memory)两种。我们平常在Thread中操作这些变量,其实是操作的主存储器的一个副本。当修改完之后,还需要重新刷到主存储器上,其他的线程才能够知道这些变化。

1.3 Java中常见的线程同步方式

为了完成JMM的操作,完成线程之间的变量同步,Java提供了非常多的同步手段。

  1. Java的基类Object中,提供了wait和notify的原语,来完成monitor之间的同步。不过这种操作我们在业务编程中很少遇见

  2. 使用synchronized对方法进行同步,或者锁住某个对象以完成代码块的同步

  3. 使用concurrent包里面的可重入锁。这套锁是建立在AQS之上的

  4. 使用volatile轻量级同步关键字,实现变量的实时可见性

  5. 使用Atomic系列,完成自增自减

  6. 使用ThreadLocal线程局部变量,实现线程封闭

  7. 使用concurrent包提供的各种工具,比如LinkedBlockingQueue来实现生产者消费者。本质还是AQS

  8. 使用Thread的join,以及各种await方法,完成并发任务的顺序执行

从上面的描述可以看出,多线程编程要学的东西可实在太多了。幸运的是,同步方式虽然千变万化,但我们创建线程的方式却没几种。

第一类就是Thread类。大家都知道有两种实现方式。第一可以继承Thread覆盖它的run方法;第二种是实现Runnable接口,实现它的run方法;而第三种创建线程的方法,就是通过线程池。

其实,到最后,就只有一种启动方式,那就是Thread。线程池和Runnable,不过是一种封装好的快捷方式罢了。

多线程这么复杂,这么容易出问题,那常见的都有那些问题,我们又该如何避免呢?下面,我将介绍10个高频出现的坑,并给出解决方案。

转载:Java多线程:从基本概念到避坑指南 (qq.com)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值