线程安全问题: 某个函数或函数库在并发情况下,能够正确处理多个线程之间的共享变量,是的程序正确完成。
存在线程安全问题三条件,缺一不可:
1、并发
2、多线程
3、共线变量
并发
同一时间段几个进程同时在运行,并发不受cpu核心数限制,单核cpu上也可以并发,是通过时间片来让进程的执行,只不过时间片很短,就好像同一时刻发生的。
并行
受cpu核心数限制,单核不可以做到并行。当系统有两个以上的cpu时,当一个cpu在执行一个进程,另一个cpu同一时刻在执行另一个进程,同时进行这就叫做并行。
比如:
两个队列,一个咖啡机,两个队列轮流打咖啡,这就叫做并发。
两个队列,两个咖啡机,两个队列都在各自的咖啡机上打咖啡,这就叫做并行。
咖啡机就是cpu,队列就是进程
多线程
在操作系统中,CPU切换到另一个进程需要保存当前进程的状态并恢复另一个进程的状态:当前运行任务转为就绪(或者挂起、删除)状态,另一个被选定的就绪任务成为当前任务。上下文切换就是这样一个过程,他允许CPU记录并恢复各种正在运行程序的状态,使它能够完成切换操作。
一个任务就是一个进程(Process),比如打开一个浏览器就是启动一个浏览器进程,打开一个记事本就启动了一个记事本进程,打开两个记事本就启动了两个记事本进程,打开一个Word就启动了一个Word进程。
而在多个进程之间切换的时候,需要进行上下文切换。但是上下文切换势必会耗费一些资源。于是人们考虑,能不能在一个进程中增加一些“子任务”,这样减少上下文切换的成本。比如我们使用Word的时候,它可以同时进行打字、拼写检查、字数统计等,这些子任务之间共用同一个进程资源,但是他们之间的切换不需要进行上下文切换。
一个任务就是一个进程(Process),比如打开一个浏览器就是启动一个浏览器进程,打开一个记事本就启动了一个记事本进程,打开两个记事本就启动了两个记事本进程,打开一个Word就启动了一个Word进程。
在一个进程内部,要同时干多件事,就需要同时运行多个“子任务”,我们把进程内的这些“子任务”称为线程(Thread)。
注:上下文切换是在进程间,线程之间不存在上下文切换
在一个进程内部,要同时干多件事,就需要同时运行多个“子任务”,我们把进程内的这些“子任务”称为线程(Thread)。
把进程当做资源分配的基本单元,把线程当做执行的基本单元,同一个进程的多个线程之间共享资源。
比如 java程序运行在jvm上,每个jvm就是一个进程。所有资源分配都是基于jvm进程来的。在这个jvm进程中可以创建多个线程,多个线程之间可以共享jvm变量,并且多个线程可以并发执行。
共享变量:
共享变量:指多个线程都可以操作的变量。
进程是分配资源的基本单位,而线程是执行的基本单位。因此多个线程之间是可以共享一部分进程中的数据。在jvm中,java堆和方法区的区域是线程共享的数据。也就是说多个线程可以操作在堆中的数据或者方法区中的数据。 换句话说,保存在堆和方法区的数据就是java的共享变量。
java中有三种变量:类变量(方法区)、成员变量(堆)、局部变量(栈)
因此java的共享变量是有类变量、成员变量。 因此在操作类变量和成员变量时要考虑线程安全问题。
网友评论