001_重拾多线程之线程安全问题总结

什么是线程安全?

当多个线程访问某个类时,这个类始终都能表现出正确的行为,那么就称这个类是线程安全的。(出自并发编程实战)

多个线程访问某个类时,不管运行时环境采用何种调度方式或者这些线程将如何交替执行,并且在主调代码中不需要任何额外的同步或协同,这个类都能表现出正确的行为,那么就称呼这个类是线程安全的。

有几个问题需要清楚:

  1. 并发与并行的关系:
  2. 线程与进程的关系:
  3. 共享变量问题:

并发(concurrent)与并行(parallel):

       这是两个非常容易被混淆的概念。它们都可以表示两个或者多个任务一起执行,但是偏重点有些不同。并发偏重于多个任务交替执行,而多个任务之间有可能还是串行的。而并行是真正意义上的‘同时执行’。

       并行的多个任务是真实的同时执行,而对于并发来说,这个过程只是交替的,一会儿运行任务A 一会儿执行任务B,系统会不停滴在两者间切换。但对于外观观察者来说,即使多个任务之间是串行并发的,也会造成多任务间是并行执行的错觉

      所以如果系统内只有一个CPU,而使用多进程或者多线程任务,那么真实环境中这些任务不可能是真实并行的,毕竟一个CPU一次只能执行一条指令,这种情况下多进程或者多线程就是并发的,而不是并行的(操作系统会不停切换多个任务)。真实的并行也只可能出现在拥有多个CPU的系统中(比如多核CPU)。

线程与进程

      对于操作系统而言,一个任务就是一个进程(process),比如打开一个记事本就等于启动了一个记事本进程,打开两个记事本就启动了两个记事本进程等等。

      为了达到‘同时干多件事情’,分时操作系统是把CPU时间划分成长短基本相同的‘时间片’,通过操作系统的管理,把这些时间片依次轮流地分配给各个用户的各个任务使用。

    在多任务处理系统中,CPU需要处理所有程序的操作,当用户来回切换它们时,需要记录这些程序执行到哪里。在操作系统中,CPU切换到另一个进程的状态;当前运行任务转为就绪(挂起、或者删除)状态,另一个被选定的就绪任务成为当前任务。上下文切换就是这样一个过程,他允许CPU记录并恢复各种正在运行程序的状态,使其能完成切换操作。

     在上下文切换中,CPU会停止处理当前运行的程序,并保存当前程序运行的具体位置以便之后继续运行。来回的切换中,我们需要记住每本书当前读到的页码。在程序中,上下文切换过程中的‘页码’信息是保存在进程控制块(PCB)中的。PCB还经常被称作‘切换帧’。‘页码’信息会一直保存到CPU内存中,直到他们被再次使用。

    在一个进程内部,要同时干很多件事,就需要同时运行多个‘子任务’,我们把进程内的这些‘子任务’称作线程(Thread)。

进程当做资源分配的基本单元,把线程当做执行的基本单元,同一进程的多个线程之间共享资源。

共享变量

多个线程都可以访问的变量,他们之间是可以共享一部分进程中的数据的。在JVM中,Java堆和方法区的区域是多个线程共享的数据区域。

Java中共有三种变量,分别是类变量,成员变量和局部变量。分别存在于方法区,堆内存和栈内存中。

public class Variables{
    
    private static int a;
    
    private int b;

    public void test(int c){
        int d;
    }
}

 变量a就是类变量,变量b就是成员变量,而变量c和d是局部变量。所以,变量a和b是共享变量,而变量c和变量d是局部变量。所以,变量a和b是共享变量,变量c和d是非共享变量。此刻产生多线程场景问题,对于变量a和b的操作是需要考虑线程安全的,而对于线程c和d是不需要考虑的。

画的有点难看哈。。

 

 

 

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值