Posts Tagged ‘ lock

并发性能优化 – 降低锁粒度

原文链接  作者:Adrianos Dadis 译者:买蓉(sky.mairong@gmail.com) 校对:方腾飞

在高负载多线程应用中性能是非常重要的。为了达到更好的性能,开发者必须意识到并发的重要性。当我们需要使用并发时, 常常有一个资源必须被两个或多个线程共享。

在这种情况下,就存在一个竞争条件,也就是其中一个线程可以得到锁(锁与特定资源绑定),其他想要得到锁的线程会被阻塞。这个同步机制的实现是有代价的,为了向你提供一个好用的同步模型,JVM和操作系统都要消耗资源。有三个最重要的因素使并发的实现会消耗大量资源,它们是:

  • 上下文切换
  • 内存同步
  • 阻塞

Read more

Java类锁和对象锁实践

感谢[jiehao]同学的投稿,投稿可将文章发送到tengfei@ifeve.com

类锁和对象锁是否会冲突?对象锁和私有锁是否会冲突?通过实例来进行说明。

一、相关约定

为了明确后文的描述,先对本文涉及到的锁的相关定义作如下约定:

1. 类锁:在代码中的方法上加了static和synchronized的锁,或者synchronized(xxx.class)的代码段,如下文中的increament();

2.对象锁:在代码中的方法上加了synchronized的锁,或者synchronized(this)的代码段,如下文中的synOnMethod()和synInMethod();

3.私有锁:在类内部声明一个私有属性如private Object lock,在需要加锁的代码段synchronized(lock),如下文中的synMethodWithObj()。

Read more

Java锁的种类以及辨析(三):阻塞锁

下载作者:山鸡

锁作为并发共享数据,保证一致性的工具,在JAVA平台有多种实现(如 synchronized 和 ReentrantLock等等 ) 。这些已经写好提供的锁为我们开发提供了便利,但是锁的具体性质以及类型却很少被提及。本系列文章将分析JAVA下常见的锁名称以及特性,为大家答疑解惑。

Read more

Java锁的种类以及辨析

下载

作者:山鸡

锁作为并发共享数据,保证一致性的工具,在JAVA平台有多种实现(如 synchronized 和 ReentrantLock等等 ) 。这些已经写好提供的锁为我们开发提供了便利,但是锁的具体性质以及类型却很少被提及。本系列文章将分析JAVA中常见的锁以及其特性,为大家答疑解惑。

Read more

Ticket Lock的Relaxed Atomics优化

原文地址 作者:Pedro Ramalhete,译者:周可人,校对:梁海舰

Tick lock是mutual lock的一种简单实现:

http://web.mit.edu/6.173/www/currentsemester/readings/R06-scalable-synchronization-1991.pdf

它是由John Mellor-Crummey和Michael Scott在1991年提出的(pdf中2.2节),感谢C++11和C11中新的内存模型,我们可以对单个变量进行具有屏障或者不具有屏障的原子操作。当屏障没有使用,只有原子性保证时,我们称之为“relaxed atomic”:

http://en.cppreference.com/w/cpp/atomic/memory_order

注意在C11/C++11内存模型中,一个原子变量并不具有内在的“顺序一致性”或者“relaxed”性质,然而我们可以在每次访问的时选择它的行为。

原子修饰符只能保证原子性,即这个变量会被单步读或写。其他语言,如Java和Scala则不同,它们可以保证几乎所有的原生类型提供原子性保证,从而表现为“relaxed atomic”。并且,所有被声明为顺序一致性的变量可以在整个程序中保持性质(除非在Java中使用sun.misc.unsafe)。尽管这个细微的差异可能看起来并不重要,但是当我们的目标是从同步或是并发算法中挖掘最大性能时,就需要关注这个差异了。

Read more

基于锁的并发算法 vs 无锁的并发算法

原文链接 作者:Martin Thompson  译者:曹姚君 校对: 方腾飞

上周在由Heinz Kabutz通过JCrete 组织的开放空间会议(unconference)上,我参加一个新的java规范 JSR166 StampedLock的审查会议。StampedLock 是为了解决多个readers 并发访问共享状态时,系统出现的内存地址竞争问题。在设计上通过使用乐观的读操作,StampedLock 比ReentrantReadWriteLock 更加高效;

在会议期间,我突然意思到两点:

  • 第一、我想是时候该去回顾java中锁的实现的现状。
  • 第二、虽然StampedLock 看上去是JDK很好的补充,但是它视乎忽略了一个事实,即在多个reader的场景里,无锁的算法通常是更好的解决方案。

Read more

测试并发应用 (一)监控Lock接口

声明:本文是《 Java 7 Concurrency Cookbook 》的第八章, 作者: Javier Fernández González 译者:郑玉婷  

校对:方腾飞

监控Lock接口

Lock 接口是Java 并发 API提供的最基本的机制来同步代码块。它允许定义临界区。临界区是代码块可以共享资源,但是不能被多个线程同时执行。此机制是通过Lock 接口和 ReentrantLock 类实现的。

在这个指南,你将学习从Lock对象可以获取的信息和如何获取这些信息。 Read more

定制并发类(九)实现一个自定义的Lock类

声明:本文是《 Java 7 Concurrency Cookbook 》的第七章,作者: Javier Fernández González     译者:许巧辉

实现一个自定义的Lock类

锁是Java并发API提供的基本同步机制之一。它允许程序员保护代码的临界区,所以,在某个时刻只有一个线程能执行这个代码块。它提供以下两种操作:

  • lock():当你想要访问一个临界区时,调用这个方法。如果有其他线程正在运行这个临界区,其他线程将阻塞,直到它们被这个锁唤醒,从而获取这个临界区的访问。
  • unlock():你在临界区的尾部调用这个方法,允许其他线程访问这个临界区。

在Java并发API中,锁是在Lock接口及其一些实现类中声明的,比如ReentrantLock类。

在这个指南中,你将学习如何实现你自己的Lock对象,它将实现一个实现了Lock接口并可用来保护临界区的类。

Read more

基本线程同步(八)在Lock中使用多个条件

声明:本文是《 Java 7 Concurrency Cookbook 》的第二章,作者: Javier Fernández González     译者:许巧辉 校对:方腾飞

在Lock中使用多个条件

一个锁可能伴随着多个条件。这些条件声明在Condition接口中。 这些条件的目的是允许线程拥有锁的控制并且检查条件是否为true,如果是false,那么线程将被阻塞,直到其他线程唤醒它们。Condition接口提供一种机制,阻塞一个线程和唤醒一个被阻塞的线程。

在并发编程中,生产者与消费者是经典的问题。我们有一个数据缓冲区,一个或多个数据生产者往缓冲区存储数据,一个或多个数据消费者从缓冲区中取出数据,正如在这一章中前面所解释的一样。

在这个指南中,你将学习如何通过使用锁和条件来实现生产者与消费者问题。 Read more

基本线程同步(七)修改Lock的公平性

声明:本文是《 Java 7 Concurrency Cookbook 》的第二章,作者: Javier Fernández González  译者:许巧辉 校对:方腾飞

修改Lock的公平性

在ReentrantLock类和 ReentrantReadWriteLock类的构造器中,允许一个名为fair的boolean类型参数,它允许你来控制这些类的行为。默认值为 false,这将启用非公平模式。在这个模式中,当有多个线程正在等待一把锁(ReentrantLock或者 ReentrantReadWriteLock),这个锁必须选择它们中间的一个来获得进入临界区,选择任意一个是没有任何标准的。true值将开启公平 模式。在这个模式中,当有多个线程正在等待一把锁(ReentrantLock或者ReentrantReadWriteLock),这个锁必须选择它们 中间的一个来获得进入临界区,它将选择等待时间最长的线程。考虑到之前解释的行为只是使用lock()和unlock()方法。由于tryLock()方 法并不会使线程进入睡眠,即使Lock接口正在被使用,这个公平属性并不会影响它的功能。

在这个指南中,我们将修改使用Lock同步代码块食谱示例来使用这个属性,并且观察公平与非公平模式之间的差别。 Read more

基本线程同步(六)使用读/写锁同步数据访问

声明:本文是《 Java 7 Concurrency Cookbook 》的第二章,作者: Javier Fernández González     译者:许巧辉

使用读/写锁同步数据访问

锁所提供的最重要的改进之一就是ReadWriteLock接口和唯一 一个实现它的ReentrantReadWriteLock类。这个类提供两把锁,一把用于读操作和一把用于写操作。同时可以有多个线程执行读操作,但只有一个线程可以执行写操作。当一个线程正在执行一个写操作,不可能有任何线程执行读操作。

在这个指南中,你将会学习如何使用ReadWriteLock接口实现一个程序,使用它来控制访问一个存储两个产品价格的对象。 Read more

基本线程同步(五)使用Lock同步代码块

声明:本文是《 Java 7 Concurrency Cookbook 》的第二章,作者: Javier Fernández González     译者:许巧辉 校对:方腾飞

使用Lock同步代码块

Java提供另外的机制用来同步代码块。它比synchronized关键字更加强大、灵活。它是基于Lock接口和实现它的类(如ReentrantLock)。这种机制有如下优势:

  • 它允许以一种更灵活的方式来构建synchronized块。使用synchronized关键字,你必须以结构化方式得到释放synchronized代码块的控制权。Lock接口允许你获得更复杂的结构来实现你的临界区。
  • Lock 接口比synchronized关键字提供更多额外的功能。新功能之一是实现的tryLock()方法。这种方法试图获取锁的控制权并且如果它不能获取该锁,是因为其他线程在使用这个锁,它将返回这个锁。使用synchronized关键字,当线程A试图执行synchronized代码块,如果线程B正在执行它,那么线程A将阻塞直到线程B执行完synchronized代码块。使用锁,你可以执行tryLock()方法,这个方法返回一个 Boolean值表示,是否有其他线程正在运行这个锁所保护的代码。
  • 当有多个读者和一个写者时,Lock接口允许读写操作分离。
  • Lock接口比synchronized关键字提供更好的性能。

在这个指南中,你将学习如何通过锁来同步代码块和通过Lock接口及其实现者ReentrantLock类来创建临界区,实现一个程序来模拟打印队列。
Read more

深入理解并行编程-锁

原文链接    作者:paul    译者:谢宝友,鲁阳,陈渝

在过去几十年并发研究领域的出版物中,锁总是扮演着坏人的角色,锁背负的指控包括引起死锁、锁封护(luyang注:lock convoying,多个同优先级的线程重复竞争同一把锁,此时大量虽然被唤醒而得不到锁的线程被迫进行调度切换,这种频繁的调度切换相当影响系统性能)、饥饿、不公平、data races以及其他许多并发带来的罪孽。有趣的是,在共享内存并行软件中真正承担重担的是——你猜对了——锁。

1

图1.1:锁:坏人还是懒汉? Read more

Java并发性和多线程介绍目录

concurrency

原文地址   译文地址  译者:张坤等

  1. Java并发性和多线程介绍
  2. 多线程的优点
  3. 多线程的代价
  4. 并发编程模型
  5. 如何创建并运行java线程
  6. 竞态条件与临界区
  7. 线程安全与共享资源
  8. 线程安全及不可变性
  9. Java内存模型
  10. JAVA同步块
  11. 线程通信
  12. Java ThreadLocal
  13. Thread Signaling (未翻译)
  14. 死锁
  15. 避免死锁
  16. 饥饿和公平
  17. 嵌套管程锁死
  18. Slipped Conditions
  19. Java中的锁
  20. Java中的读/写锁
  21. 重入锁死
  22. 信号量
  23. 阻塞队列
  24. 线程池
  25. CAS
  26. 剖析同步器
  27. 无阻塞算法
  28. 阿姆达尔定律

饥饿和公平

原文地址  By Jakob Jenkov  翻译 Simon-SZ  校对:方腾飞

如果一个线程因为CPU时间全部被其他线程抢走而得不到CPU运行时间,这种状态被称之为“饥饿”。而该线程被“饥饿致死”正是因为它得不到CPU运行时间的机会。解决饥饿的方案被称之为“公平性” – 即所有线程均能公平地获得运行机会。

 下面是本文讨论的主题:

1. Java中导致饥饿的原因:

  • 高优先级线程吞噬所有的低优先级线程的CPU时间。
  • 线程被永久堵塞在一个等待进入同步块的状态。
  • 线程在等待一个本身也处于永久等待完成的对象(比如调用这个对象的wait方法)。

2. 在Java中实现公平性方案,需要:

  • 使用锁,而不是同步块。
  • 公平锁。
  • 注意性能方面。 Read more

return top