多线程并发编程(一)

系列文章目录

多线程并发编程系列



提示:以下是本篇文章正文内容

一、进程、线程、并发、并行、的基础概念

进程:进程是程序在执行过程中分配和管理资源的基本单位。

线程: 线程是cpu调度和分配资源的最小单位。

并发:并发是针对单个cpu来说的,多个线程轮流在一个cpu上执行任务,当时间片用完后,会切换到下一个线程使用,这也是我们常说的线程的上下文切换。实际上多个线程是依次执行任务的,并且速度非常快,看上去像是多个线程一起执行一样。我们可以这样形容并发,在单个cpu上的一个时间段内,线程依次执行。

并行:并行是针对多核来说的,可以把多核说成多个cpu,在多核环境中一个cpu对应一个线程,比如8核,我们如果开了8个线程的话,每个线程分配一个cpu,这时他们是同时执行任务的,在一个时间点上齐头并进。如果有20个线程呢,这时当8个线程首先占好位置后,剩下的12个线程要等待前面线程的时间片用完才能轮到他们。所以我们可以这样说,如果看前8个线程,他们是并行的,因为是在同一个时间点启动的。但是看20个线程呢,他们是并发的,他们会在一段时间后才能执行完成。

所以我们java项目部署的应用服务器有 4核、8核、16、32、64核的说法,核数越多,我们可以开的线程也就越多,但是也不能开过多的线程,否则单个线程的任务执行时间也会变长。一般我们开的线程是大于核心数的,这样才能充分利用多核的优势。

二、什么时候考虑引入多线程

我们先看多线程的作用:异步、 缩短长任务时间
举个例子,包工头指挥工人干活, 1个人需要300天,那么理论上10个人只要30天, 100个人只要3天,而包工头自己可以做其他的事,直接向老板反馈目前进度(异步),而工人还在干活(多线程缩短长任务时间)这样就把一个长任务拆解成数十个小任务,时间就缩短了10倍。

一般我们耗时较长的需求就可以考虑加入多线程了,比如导入导出、复杂的耗时计算、或者需要先返回结果的需求,让任务在后台慢慢处理,先把处理中的状态返回给前端。

三、多线程使用的注意事项

1线程不是开的越多越好

对于一个服务器而言,能开辟的线程总数是有限(受限于cpu的性能、虚拟空间的大小、栈 的大小的限制、操作系统的位数、什么操作系统)一般的小型系统设置几百就够了,通过集群的方式能处理些并发量不高的功能模块。

对于线程池而言,因为线程属于一种宝贵资源,所以能少开尽量少开,比如使用ThreadPoolExecutor线程池设置的核心线程数是常驻线程,并不会进行销毁,所以线程池的核心线程要合理设置否则也会给系统带来负担。对于不经常调用的接口,可以利用
static {
executor.allowCoreThreadTimeOut(true);
}
把核心线程设置超时时间自动销毁掉。

2 多线程带来的线程安全问题

当多个线程对同一共享资源并发进行读写的时候,就有可能发生线程安全问题,对于方法内的资源是每个线程独有的,不需要考虑,但是方法外的比如说成员变量 new一个arrayList,就需要通过加锁来控制同时只有一个线程来访问。我们引申下,数据库中的数据同样也是属于共享资源,mysql通过数据库的共享锁(S)、排它锁锁(X)、意向共享锁(IS)、意向排他锁(IX)来保证资源的安全问题。

需要注意的是如果是分布式环境,需要考虑你的业务是不是需要保证就算有多个节点,同一个方法也只允许一个线程进入。普通的锁是JVM层面的锁,只能保证当前机器中的同一个方法在同一时间只能被一个线程访问,他保证不了其他机器部署的相同应用的同一个方法的安全性。我们需要借助分布式锁来保证就算有多台机器,同一时间只有一个线程来执行某一个方法。

总结

这篇文章主要讲的是多线程并发编程的应用层面的理解使用,后面的文章会把上面介绍的点,详细的进行介绍

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值