多线程中的互斥控制程序代码_单线程改多线程及处理细节

某些编程语言被设计为可以将并发任务彼此隔离,这些语言通常称为函数型语言,其中每个函数调用都不会产生任何副作用(并因此而不能干涉其他函数),并因此可以当做独立的任务来驱动。Erlang就是这样的语言。

Java采取了更加传统的方式,在顺序性语言的基础上提供对线程的支持。与在多任务操作系统中分叉外部进程不同,线程机制是在由执行程序表示的单一进程中创建任务。这种方式产生的一个好处是操作系统的透明性,这对Java而言,是一个重要的设计指标。

Java的线程机制是抢占式的,这表示调度机制会周期性的中断线程,将上下文切换到另一个线程,从而为每个线程都提供时间片,使得每个线程都会分配到数量合理的时间去驱动他的任务。

当从Runnable导出一个类时,它必须具有run()方法,但是这个方法并无特殊之处——它不会产生任何内在的线程能力。要实现线程行为,你必须显式地将一个任务附着到线程上。

将Runnable对象转变为工作任务的传统方式时把它提交给一个Thread构造器。Thread构造器只需要一个Runnable对象。调用Thread对象的start()方法为该线程执行必须的初始化操作,然后调用Runnable的run()

方法,以便在这个新线程中启动该任务。

bbfaeb06f389df9427faeea0a9d818de.png

多线程交互模式:

  1. 不进行交互的模式:
    1. 线程间不需要处理共享的数据,也不需要进行动作协调,那么将会非常简单,就是多个独立的线程各自完成自己线程中的工作。
  1. 基于共享容器协同的多线程模式:
    1. 多个线程间对共享的数据进行处理。例如经典的生产者消费者例子,我们有一个队列用于生产和消费,那么这个队列就是多个线程会共享的一个容器或者数据对象,多个线程会并发地访问这个队列。
      在多线程环境下对同一份数据的访问,我们需要有所保护和控制以保证访问的正确性。对于存储数据的容器或者对象,有线程安全和线程不安全之分,而对于线程不安全的容器或对象,一般可以通过
      加锁或者通过Copy On Write的方式来控制并发访问。
    2. 使用加锁方式时,如果数据在多线程中的读写比例很高,则一般会采用读写锁而非简单的互斥锁。
    3. 对于线程安全的容器和对象,我们就可以在多线程环境下直接使用它们了。在这些线程安全的容器和对象中,有些是支持并发的,这种方式的效率会比简单的加互斥锁的实现更好,在JDK中的
      java.util.concurrent包中有很多这样的容器类。(注:比如HashMap改CurrentHashMap时,要注意之前的锁粒度,操作的原子性)
  1. 通过事件协同的多线程模式:
    1. 除了并发访问的控制,线程间会存在着协调的需求,例如A、B两个线程,B线程需要等到某个状态或事件发生后才能继续自己的工作,而这个状态改变或者事件产生需要和A线程相关。那么在这个场景
      下,就需要线程间的协调。
    2. 避免死锁,一般来说,能够原子性的获取需要的多个锁,或者注意调整获取多个锁的获取顺序,就会比较好地避免死锁。
    3. 此外,线程之间还会传递数据。因为这些线程共用进程的内存空间,所以线程间的传递数据就相对容易一些了。
  1. 多进程模式:
    1. 多进程相对于单进程下的多线程方式来说,资源控制会更容易实现,此外,多进程中的单个进程问题,不会造成整体的不可用。这两天是多进程区别于单进程多线程方式的两个特点。
      当然,使用多进程会比多线程稍微复杂一些。多进程间可以共享数据,但是其代价比多线程要大,会涉及序列化与反序列化的开销。
    2. 我们的分布式系统是多机组成的系统,可以近似看作是把单机多进程变成了多机的多进程。

可用性分析:

单线程和单进程多线程的程序在遇到机器故障、OS问题或者自身的进程问题时,会导致整个功能不可用。

对于多进程的系统,如果遇到机器故障或者OS问题,那么功能也会整体不可用,而如果是多进程中的某个进程问题,那么是有可能保持系统的部分功能正常的——当然这取决于多进程系统自身的实现方式。

而在多机系统中,如果遇到某些机器故障、OS问题或者某些机器的进程问题,我们都有机会来保证整体的功能大体可用——可能是部分功能失效,也可能是不再能承担正常情况下那么大的系统压力了。

综上,不同的方式可能造成的故障影响面也是不同的。

节选《大型网站系统与Java中间件实践》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值