`
沉沦的快乐
  • 浏览: 55695 次
  • 性别: 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,则不能获得锁,开发人员可以根据场景对不同结果进行处理。

 

 

分享到:
评论

相关推荐

    并发编程实践,全面介绍基础知识、JVM同步原语、线程安全、低级并发工具、线程安全容器、高级线程协作工具、Executor部分等

    详细介绍java并发编程相关知识: 基础知识   并发与并行   Java并发演进历史   Java并发模型   线程模型   存储模型 JVM同步原语 volatile CAS 线程安全   保护“共享数据” 低级并发工具   原子变量   锁...

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

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

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

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

    JAVA并发编程实践 .pdf

    《Java并发编程实战》深入浅出地介绍了Java线程和并发,是一本完美的Java并发参考手册。书中从并发性和线程安全性的基本概念出发,介绍了如何使用类库提供的基本并发构建块,用于避免并发危险、构造线程安全的类及验证...

    Java并发编程实战

    1.1 并发简史 1.2 线程的优势 1.2.1 发挥多处理器的强大能力 1.2.2 建模的简单性 1.2.3 异步事件的简化处理 1.2.4 响应更灵敏的用户界面 1.3 线程带来的风险 1.3.1 安全性问题 1.3.2 活跃性问题 1.3.3 ...

    Java并发编程实战.rar

    《Java并发编程实战》是一本完美的Java并发参考手册。书中从并发性和线程安全性的基本概念出发,介绍了如何使用类库提供的基本并发构建块,用于避免并发危险、构造线程安全的类及验证线程安全的规则,如何将小的线程...

    Java 7并发编程实战手册

    如果你是一名Java开发人员,并且想进一步掌握并发编程和多线程技术,并挖掘Java 7并发的新特性,那么本书是你的合适之选。 《Java 7并发编程实战手册》 第1章 线程管理 1 1.1 简介 1 1.2 线程的创建和运行...

    汪文君高并发编程实战视频资源全集

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

    Java并发编程实践

    《Java并发编程实战》深入浅出地介绍了Java线程和并发,是一本完美的Java并发参考手册。书中从并发性和线程安全性的基本概念出发,介绍了如何使用类库提供的基本并发构建块,用于避免并发危险、构造线程安全的类及...

    Java并发编程实战.pdf

    如何提高单线程子系统的响应性,如何确保并发程序执行预期任务,如何提高并发代码的性能和可伸缩性等内容,最后介绍了一些高级主题,如显式锁、原子变量、非阻塞算法以及如何开发自定义的同步工具类。

    Java并发编程实战 (带完整书签扫描版)

    《Java并发编程实战》是一本完美的Java并发参考手册。书中从并发性和线程安全性的基本概念出发,介绍了如何使用类库提供的基本并发构建块,用于避免并发危险、构造线程安全的类及验证线程安全的规则,如何将小的线程...

    java并非编程,合集(各种锁、并发集合、障碍器、线程同步).zip

    java并非编程,合集(各种锁、并发集合、障碍器、线程同步)

    Java并发编程实践 PDF 高清版

    本书的读者是那些具有一定Java编程经验的程序员、希望了解Java SE 5,6在线程技术上的改进和新特性的程序员,以及Java和并发编程的爱好者。 目录 代码清单 序 第1章 介绍 1.1 并发的(非常)简短历史 1.2 线程的...

    java并发编程实战相关书籍

    如何提高单线程子系统的响应性,如何确保并发程序执行预期任务,如何提高并发代码的性能和可伸缩性等内容,最后介绍了一些高级主题,如显式锁、原子变量、非阻塞算法以及如何开发自定义的同步工具类

    Java多线程编程 线程同步机制.docx

    锁正是基于这种思路实现的一种线程同步机制。 在对共享数据加锁后,每个线程在访问共享数据时必须先申请相应的锁。一旦获得锁后,就可以访问共享数据,并且一个锁同一时刻只能被一个线程持有,这意味着获得锁后不会...

    JAVA并发编程实践 带书签

    如何提高单线程子系统的响应性,如何确保并发程序执行预期任务,如何提高并发代码的性能和可伸缩性等内容,最后介绍了一些高级主题,如显式锁、原子变量、非阻塞算法以及如何开发自定义的同步工具类。

    Java并发编程实战(华章专业开发者书库).mobi

    如何提高单线程子系统的响应性,如何确保并发程序执行预期任务,如何提高并发代码的性能和可伸缩性等内容,最后介绍了一些高级主题,如显式锁、原子变量、非阻塞算法以及如何开发自定义的同步工具类。 本书适合Java...

    Java 并发编程实战(中文+高清版).zip

    如何提高单线程子系统的响应性,如何确保并发程序执行预期任务,如何提高并发代码的性能和可伸缩性等内容,最后介绍了一些高级主题,如显式锁、原子变量、非阻塞算法以及如何开发自定义的同步工具类。

    Java 并发编程实战

    1.1 并发简史 1.2 线程的优势 1.2.1 发挥多处理器的强大能力 1.2.2 建模的简单性 1.2.3 异步事件的简化处理 1.2.4 响应更灵敏的用户界面 1.3 线程带来的风险 1.3.1 安全性问题 1.3.2 活跃性问题 1.3.3 ...

    《Java并发编程实战》

    《Java并发编程实战》深入浅出地介绍了Java线程和并发,是一本完美的Java并发参考手册。书中从并发性和线程安全性的基本概念出发,介绍了如何使用类库提供的基本并发构建块,用于避免并发危险、构造线程安全的类及验证...

Global site tag (gtag.js) - Google Analytics