软件构造复习内容(9)---并发(1)

1.并发:

  网络上多台计算机,一台计算机上多个应用,一个CPU上的多核处理器,都可以算作并发。

  为了充分利用多核和多处理器,需要将程序转化为并发执行

  并发的两个Model:

  1.共享内存

  2.消息传递,通过channel交换消息

2.进程和线程:

  进程:私有空间,彼此隔离

    1.拥有整台计算机的资源

    2.多个进程之间不共享内存

    3.进程之间通过消息传递进行协作

    一般来说 进程==程序==应用

    但是一个应用中可能包含多个进程

    JVM通常运行单一进程,但也可以创建新的进程

  线程:程序内部的控制机制

    1.线程=虚拟CPU

    2.程序共享,资源共享都隶属于进程

    3.共享内存

    4.很难获得线程的私有内存空间

    5.通过创建消息队列在线程之间进行消息传递

3.在Java中开始一个线程

  方法一:从Thread类派生一个子类

    

   要改写的run方法是线程开始之后执行的方法

  开始一个线程的方法是  start();

  方法二:从Runnable接口构造Thread对象

  

4.交错和竞争

  (1)时间分片

    虽然有多线程,但是只有一个核,每个时刻只能执行一个线程,通过时间分片,在多个进程/线程之间共享处理。

  (2)线程之间共享内存

  (3)竞争(Race Condition)

    程序的正确性依赖于在并发条件下执行的顺序

  例如:

  

   B覆盖了A的添加,导致A的添加没有加到balance上,然后写回了之后,balance少了1.

     原子语句之间不会发生竞争,但是单行,单条语句都未必是原子的,是否原子,有JAM确定。

  Race Condition又被称为线程干扰,是必须避免的情况

  消息传递机制也无法解决竞争条件问题,仍然存在消息传递时间上的交错

5.并发程序难以test和debug

  因为Interleaving(交错)的存在,并发错误难以复现

  bug类型

  Heisenbugs:难以再现

  Bohrbugs:可以再现

6.利用某些方法调用来主动影响线程之间的interlraving关系

  1.Thread.sleep(long time)

    线程休眠time毫秒

    直接原句指定当前正在运行的线程休眠,指定具体的线程使具体的线程休眠

    进入休眠的线程不会失去对现有monitor或锁的所有权

  2.Thread.interrupt()

    请求中断线程,该方法执行之后,线程也不一定中断。这取决于程序员的处理。

    当对一个线程调用interrupt方法时,线程的中断状态将被置位,这是每一个线程都具有的boolean标志。每个线程都会时不时检查这个标志,以判断线程是否应该被中断。

  3.isInterrupted()

    检查中断状态是否被置位。

    但是如果线程为阻塞,就无法检测中断状态,这是产生InterruptedException异常的原因,当在一个被阻塞的线程(调用了sleep或者wait之后)上调用interrupt方法时,阻塞调用将会被InterruptedException异常中断。

  有2个非常相似的方法,Interrupted和isInterrupted,Interrupted方法是一个静态方法,他检测当前线程是否被中断,而且,调用interrupted方法会清楚该线程的中断状态,另一方面。isInterrupted方法是一个实例方法,可用来检验是否有线程被中断。调用这个方法不会改变中断状态。

  中断一个线程的代码:

  

   sleep()方法会检查中断状态位,如果此时线程的中断状态被置位,那么sleep()会抛出InterruptedException异常,进入异常处理后,线程被中断。

  4.void join()

    等待终止指定的进程。让线程保持执行,知道其执行结束。

    显示指定线程的执行次序。

猜你喜欢

转载自www.cnblogs.com/guiququ/p/13196357.html
今日推荐