`
沉沦的快乐
  • 浏览: 56864 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

并发编程之线程同步锁

阅读更多

     线程同步的风险

     使用多线程可以让你充分利用多核处理器的资源,更简单的处理异步事件等。但是多线程有3个非常需要关注和解决的风险:

    1.安全性风险:即每一次系统运行的最终结果都是与预期相符的,不会产生各种稀奇古怪无法预知的结果。

    2.活动度风险:即预期会发生的事件最终会发生,而不是进入一种永远不会发生的状态。一个典型的事件就是死锁。

    3.性能风险:良好的多线程设计能获得良好的性能,但是设计不好的系统反而可能使性能下降。多线程的性能开销主要来源于两个方面:1是线程同步带来的开销,2是线程上下文切换带来的开销。

      而上述3大风险的解决或产生,无疑都与线程同步息息相关。安全性需要线程同步来解决,线程同步可能发生死锁导致活跃度失败的风险,即使解决了安全性和避免了活跃度失败的风险,这时候系统可以实现你的功能了,但是也并不意味着你线程同步没有问题,还有可能系统性能大大降低了。

    可以说线程同步是并发编程设计中最核心的问题,下面讲讲几种常用的线程同步方式

volatile关键字

 

       线程同步包含两方面的含义:一是可见性,保证获得的数据时最新的;二是原子性,原子性是不可分割的最小粒度的操作步骤。操作过程中只有一个线程在运行,不可被其他线程中断、更改。在没有同步的情况下,一个最小粒度的原子是一个机器指令。而线程同步可以使一组操作指令成为原子性。volatile关键字是一种比较弱的同步方式,他不会对它声明的对象加锁,也不会线程造成阻塞,它只保证可见性,不保证原子性。用volatile声明的属性只保证你读到的是最新的值,并不能保证a++是同步的。所以,为防止volatile被滥用,一般满足以下3个条件才能安全的使用volatile:

1,写入新的值时,并不依赖于当前的值;或者能保证只有一个线程能修改值。

2,变量不需要与其他的变量共同参与不变性约束。

3,访问变量时,没有其他的原因需要加锁。

 

原子类

     java为大部分基本类型提供了原子类。比如AtomicInteger, AtomicLong和AtomicBoolean。这些类用法基本相似,他不当保证了get/set的同步,同时还为常用的自增自减操作提供了同步方法decrementAndGet,getAndDecrement,incrementAndGet,getAndIncrement

信号量Semaphore

      当一个线程想要访问某个共享资源,首先,它必须获得semaphore。如果semaphore的内部计数器的值大于0,那么semaphore减少计数器的值并允许访问共享的资源。计数器的值大于0表示,有可以自由使用的资源,所以线程可以访问并使用它们。如果semaphore的计数器的值等于0,那么semaphore让线程进入休眠状态一直到计数器大于0。计数器的值等于0表示全部的共享资源都正被线程们使用,所以此线程想要访问就必须等到某个资源成为自由的。Semaphore对象的构造参数可以传信号上线,当上限为1时就相当于锁。semaphore.acquire()获取信号,该方法阻塞一定到其他线程释放信号。semaphore.release()执行完锁住的代码之后,需要释放信号,让其他等待的线程能够获取访问资格。

synchronized关键字

synchronized声明方法

      只有一个执行线程将会访问一个对象中被synchronized关键字声明的方法。如果另一个线程试图访问同一个对象中任何被synchronized关键字声明的方法,它将被阻塞,直到第一个线程结束方法的执行。几点说明:1.只要有一个线程锁住了对象中的一个synchronized方法,那么其他线程将不能访问这个对象中的任何一个被声明为synchronized的方法。 对于synchronized声明的方法,锁是当前实例对象。

2.如果静态方法被声明为synchronized,此时锁是当前类的class对象。只有一个线程能够访问该静态方法。但是,其他线程可以访问该类的一个对象中的其他非静态的方法。 你必须非常小心这一点,因为两个线程可以访问两个不同的同步方法,如果其中一个是静态的而另一个不是。如果这两种方法改变相同的数据,你将会有数据不一致 的错误。

3.由于synchronized会锁住这个方法的整个代码,所以一般适合于比较简单、执行效率高的方法,否则将可能导致性能严重下降。

synchronized锁住一段代码

      由于某些方法可能比较复杂,synchronized声明方法会使性能下降,所以可以使用synchronized包含需要同步的代码段,此时锁是synchronized括号里包含的对象当你使用synchronized关键字来保护代码块时,必须通过一个对象的引用作为参数,比如经常用的是synchronized(this){code}。但是如果对象中有两个以上的属性需要独立上锁时,用同一个锁则会对性能造成影响。这时可以在对象中创建多个object对象,通过声明不同的synchronized(object1){code1},synchronized(object2){code2}来分别给不同的属性操作方法上锁。

 

使用Lock

      Lock比synchronized关键字更加强大、灵活。很多用的比较多的锁,比如可重入锁,读写锁都在用Lock实现的。同时Lock还提供了tryLock方法来获得锁,并立即返回,不会使线程休眠。如果tryLock返回true,表示可以获取锁,如果返回false,则不能获得锁,开发人员可以根据场景对不同结果进行处理。

 

 

分享到:
评论

相关推荐

    vc++中的线程锁(线程锁保持线程同步)

    在VC++编程环境中,线程同步是一个至关重要的概念,特别是在多线程程序设计中,以确保并发执行的线程能够安全地访问共享资源,避免数据竞争和其他潜在的问题。本篇文章将详细探讨线程锁在VC++中的应用,以及如何通过...

    基于Java并发编程的多线程同步与锁机制.zip

    基于Java并发编程的多线程同步与锁机制 项目简介 本项目旨在深入探讨Java并发编程中的多线程同步与锁机制,涵盖了从基础的线程创建、同步方法到高级的并发工具类如ReentrantLock、ReadWriteLock、Atomic类等的...

    汪文君高并发编程实战视频资源下载.txt

    │ 高并发编程第二阶段16讲、多线程读写锁分离设计模式讲解-上.mp4 │ 高并发编程第二阶段17讲、多线程读写锁分离设计模式讲解-中.mp4 │ 高并发编程第二阶段18讲、多线程读写锁分离设计模式讲解-下.mp4 │ 高...

    C#多线程开发之并发编程经典实例.zip

    本资源“C#多线程开发之并发编程经典实例”提供了丰富的实例,旨在帮助C#开发者深入理解并掌握多线程技术。以下是关于C#多线程和并发编程的一些关键知识点: 1. **线程基础**:线程是操作系统分配CPU时间的基本单位...

    多线程并发编程-同步与互斥-原⼦变量-并发和⽆锁 数据结构

    信号灯、互斥量、自旋锁和条件变量等都是实现线程同步和互斥的机制。线程同步和互斥的机制可以通过原子变量来实现。 5.3 线程同步和互斥 线程同步和互斥是多线程编程的核心技术之一。信号灯、互斥量、自旋锁和条件...

    java线程与并发编程实践

    Java线程与并发编程实践是Java开发者必备的技能之一,特别是在多核处理器和高并发应用环境中,有效地管理和利用线程能极大地提升程序的性能。本书《java线程与并发实践编程》由Jeff Friesen撰写,2017年2月出版,...

    Java 并发编程实战.pdf

    书中会首先介绍Java并发编程的基础知识,包括线程的创建和运行,同步机制的基本用法,以及Java内存模型的相关概念。随着章节的深入,作者可能会更深入地讲解Java提供的并发工具,例如锁、原子变量、线程池、以及并发...

    java并发编程:线程基础

    Java并发编程中的线程基础是理解多线程编程的关键,它涵盖了从线程的创建到管理,再到线程间通信的全过程。多线程编程在处理高性能和高响应性的应用程序时至关重要,因为它允许程序在单个进程中同时执行多个任务,...

    《java 并发编程实战高清PDF版》

    在Java并发编程中,多线程是核心概念之一。多线程允许程序同时执行多个任务,从而充分利用系统资源,提高程序性能。然而,多线程编程也带来了同步和竞态条件等问题,这需要开发者具备良好的线程管理和同步机制的知识...

    java并发编程2

    3. **线程同步机制** - **`synchronized` 关键字** 可以保证代码块或方法在同一时刻只有一个线程访问,防止数据不一致。 - ** volatile** 关键字 用于保证变量的可见性,但不保证原子性。 - **Lock接口与...

    java并发编程艺术

    并发编程的核心概念包括线程、同步、锁机制以及并发集合等。线程是并发执行的基本单位,Java通过Thread类提供了线程的创建和管理。描述中反复提到“java并发编程艺术”,这暗示书中将详细介绍如何优雅地设计和管理...

    C++并发编程实践 C++ Concurrency in Action

    - **线程同步**:使用`join()`方法等待线程完成,或者使用`detach()`方法将线程分离为后台线程。 - **线程标识**:每个线程都有一个唯一的标识符,可以通过`get_id()`方法获取。 #### 三、线程间数据共享 第三章...

    java 并发编程的艺术pdf清晰完整版 源码

    7. **并发异常处理**:在并发编程中,正确处理异常是非常重要的,书中会讲解如何在多线程环境中优雅地处理异常。 8. **JVM内存模型与并发**:JVM内存模型对并发编程有直接影响,书中会阐述Java内存模型(JMM)的...

    Java并发编程实战华章专业开发者书库 (Tim Peierls 等 美Brian Goetz).pdf

    第四部分深入探讨了Java并发编程的高级主题,包括显式锁(如ReentrantLock)、原子变量(Atomic类)、非阻塞算法以及自定义同步组件的开发。这些高级主题帮助开发者解决复杂并发场景下的问题,实现更高层次的并发...

    JAVA并发编程实践.pdf+高清版+目录 书籍源码

    Java并发API包括了线程、锁、同步、并发容器等丰富的工具,使得开发者可以构建能够充分利用多核处理器性能的应用程序。本书详细介绍了这些主题,并提供了实例代码和实践建议。 首先,书中详细讨论了Java线程的创建...

    JAVA并发编程艺术pdf版

    通过深入学习《JAVA并发编程艺术》,开发者能更好地理解并发编程的原理,熟练运用Java提供的并发工具和API,解决实际开发中的多线程问题,提高软件的性能和稳定性。这是一本值得每一位Java开发者研读的书。

    java并发编程内部分享PPT

    总的来说,这份“java并发编程内部分享PPT”涵盖了Java并发编程的多个重要方面,包括线程创建与管理、同步机制、并发容器、线程池、并发问题以及异步计算。通过深入学习和实践这些知识点,开发者可以更好地应对多...

    Java并发编程实践高清pdf及源码

    3. **并发容器**:包括`ConcurrentHashMap`、`CopyOnWriteArrayList`和`BlockingQueue`等,这些容器在设计时考虑了并发性能,避免了线程同步的开销。 4. **线程池**:`ExecutorService`是Java并发框架的核心,它...

    深入理解并发编程

    综上所述,《深入理解并发编程》一书应涵盖并发编程的基础理论、内存模型、同步机制、多线程编程技巧、常见问题的解决方案以及高效编程实践。掌握这些知识,能够帮助开发者在多核处理器时代编写出既高效又稳定的并发...

Global site tag (gtag.js) - Google Analytics