7-1 并发

一、什么是并发编程

并发:多个计算同时运行、同一时刻多个应用运行。

并发可以充分利用多核处理器。

并发编程的两个模型:1、共享内存,并发的模块共享数据;2、消息传递,并发的模块通过传递消息来进行交互。

二、进程、线程

进程是一个正在执行的程序的实例,是私有空间,彼此隔离的。线程是一个程序的一部分,是程序内部的控制机制,一个程序可以包含一个或多个线程。

1、进程

进程拥有整台计算机的资源(虚拟的),多进程之间不共享内存,互不干扰,通过消息传递进行协作。一个应用可能包含多个进程。

2、线程

线程是虚拟CPU,线程间共享程序、共享资源、共享内存,但都属于某进程。通过消息队列在线程之间进行消息传递。每个线程有自己的方法栈、寄存器。

3、启动一个线程

可以继承Thread类,然后使用start方法启动:
在这里插入图片描述

也可以实现Runnable接口,然后用new Thread构造Thread对象:
在这里插入图片描述

实现Runnable接口可以通过匿名类实现:
在这里插入图片描述

注意,启动线程要用start而不是run,如果使用run那就只是一个普通方法。

例子:下图最多有3个线程同时运行,main也是一个:
在这里插入图片描述

三、交错和竞争

1、时间分片

通过时间分片,多个线程共享处理器。main线程结束之后,由main启动的线程也可以执行。

2、线程间共享内存

比如说所有线程共享一个balance对象:
在这里插入图片描述

如果有多个这样的线程执行的话,按理说每次存取完balance都应该是0,但由于线程的交错,可能会出现下下图这样的情况,导致出错:
在这里插入图片描述
在这里插入图片描述

3、竞争

如果两个线程之间的关系可能影响程序正确性,称这两个进程之间是存在竞争的。

下图这两个线程仍然可能存在竞争,因为表面上answer比ready先被赋值,但实际上可能执行过程中answer比ready晚被赋值。即ready已经为true了,useAnswer开始了,但此时answer仍然为0,会导致useAnswer执行出错:
在这里插入图片描述

也就是说,不能被表面代码所迷惑!

例子,如下两个方法如果并发执行,x最后可能是哪些值:
在这里插入图片描述

答案是5、6、10、30。以10为例,其他类似。每一个乘法分为三步,读取、乘5、写回。有可能x*=2执行结束之后,x*=5执行,但写回那一步在x*=3之后。

竞争是非常难测试和debug的,因为很难复现场景。增加print语句可能会减少竞争bug出现的几率,由于print语句执行很慢可能影响竞争。

4、一些可以影响交错的方法

Thread.sleep让当前进程休眠;

interrupt,向其它线程发出中断信号,如果那个线程正在sleep、join、wait等,就会立即响应,并且抛出InterruptedException异常;否则,如果线程在做其他的一些事,可以自己决定是否终止。

每个进程都有一个中断状态,初始为false,interrupt方法会设置其为true;isinterrupted方法查询此状态,不改变状态;类方法Thread.interrupted查询当前进程中断状态,并将其设置为false。

join方法可以让线程保持执行直到结束:
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值