
多线程
猫头哥
创业中的猫头哥
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
java并发(八)Java同步块synchronized
笔者在刚开始使用synchronized的时候,对并发的疑惑很多.因此在这里总结一下,与大家分享.关键是"等",而不是"舍弃"线程。而且“同步”这个术语除了synchronized意外,还包括volatile、显示锁、原子变量。Java中的每一个对象都可以作为锁。对于同步实例方法,锁是当前实例对象。对于同步静态方法,锁是当前对象的Class对象。对于同步方法块,锁是Sync...2010-09-27 16:27:43 · 390 阅读 · 0 评论 -
java并发(十六)Java中的读/写锁
相比Java中的锁(Locks in Java)里Lock实现,读写锁更复杂一些。假设你的程序中涉及到对一些共享资源的读和写操作,且写操作没有读操作那么频繁。在没有写操作的时候,两个线程同时读一个资源没有任何问题,所以应该允许多个线程能在同时读取共享资源。但是如果有一个线程想去写这些共享资源,就不应该再有其它线程对该资源进行读或写(译者注:也就是说:读-读能共存,读-写不能共存,写-写不能共存)。...原创 2014-03-10 10:17:43 · 121 阅读 · 0 评论 -
java并发(十七)重入锁死
重入锁死与死锁和嵌套管程锁死非常相似。当一个线程重新获取锁,读写锁或其他不可重入的同步器时,就可能发生重入锁死。可重入的意思是线程可以重复获得它已经持有的锁。Java的synchronized块是可重入的。因此下面的代码是没问题的:(译者注:这里提到的锁都是指的不可重入的锁实现,并不是Java类库中的Lock与ReadWriteLock类)[code="java"]public cla...原创 2014-03-10 11:33:12 · 184 阅读 · 0 评论 -
java并发(十八)信号量
Semaphore(信号量) 是一个线程同步结构,用于在线程间传递信号,以避免出现信号丢失(译者注:下文会具体介绍),或者像锁一样用于保护一个关键区域。自从5.0开始,jdk在java.util.concurrent包里提供了Semaphore 的官方实现,因此大家不需要自己去实现Semaphore。但是还是很有必要去熟悉如何使用Semaphore及其背后的原理。本文的涉及的主题如下:...原创 2014-03-10 14:03:20 · 160 阅读 · 0 评论 -
java并发(十九)阻塞队列
阻塞队列与普通队列的区别在于,当队列是空的时,从队列中获取元素的操作将会被阻塞,或者当队列是满时,往队列里添加元素的操作会被阻塞。试图从空的阻塞队列中获取元素的线程将会被阻塞,直到其他的线程往空的队列插入新的元素。同样,试图往已满的阻塞队列中添加新元素的线程同样也会被阻塞,直到其他的线程使队列重新变得空闲起来,如从队列中移除一个或者多个元素,或者完全清空队列,下图展示了如何通过阻塞队列来合作:...原创 2014-03-10 14:46:44 · 118 阅读 · 0 评论 -
java并发(二十)线程池
[size=xx-large]基本介绍[/size]线程池(Thread Pool)对于限制应用程序中同一时刻运行的线程数很有用。因为每启动一个新线程都会有相应的性能开销,每个线程都需要给栈分配一些内存等等。我们可以把并发执行的任务传递给一个线程池,来替代为每个并发执行的任务都启动一个新的线程。只要池里有空闲的线程,任务就会分配给一个线程执行。在线程池的内部,任务被插入一个阻塞队列(B...原创 2014-03-10 15:02:16 · 135 阅读 · 0 评论 -
java并发(二十一)剖析同步器
虽然许多同步器(如锁,信号量,阻塞队列等)功能上各不相同,但它们的内部设计上却差别不大。换句话说,它们内部的的基础部分是相同(或相似)的。大部分同步器都是用来保护某个区域(临界区)的代码,这些代码可能会被多线程并发访问。要实现这个目标,同步器一般要支持下列功能:[list][*]状态[*]访问条件[*]状态变化[*]通知策略[*]Test-and-Set方法[*...原创 2014-03-11 18:03:05 · 120 阅读 · 0 评论 -
java并发(二十二)分布式锁
Redis有一系列的命令,特点是以NX结尾,NX是Not eXists的缩写,如SETNX命令就应该理解为:SET if Not eXists。这系列的命令非常有用,这里讲使用SETNX来实现分布式锁。[b]用SETNX实现分布式锁[/b]利用SETNX非常简单地实现分布式锁。例如:某客户端要获得一个名字foo的锁,客户端使用下面的命令进行获取:SETNX lock.foo [...原创 2014-03-12 16:24:34 · 354 阅读 · 0 评论 -
java并发(二十三)阻塞、非阻塞、同步、异步
因为中文语意的问题,很多时候确实会导致混用,而且语境不一样意义也可能不一样。如果只是从计算机编程这个角度说, 讨论最多的也是IO模型 ,阻塞非阻塞和同步异步说的应该是不同的东西。阻塞非阻塞:可以简单理解为需要做一件事能不能立即得到返回应答,如果不能立即获得返回,需要等待,那就阻塞了,否则就可以理解为非阻塞。同步异步: 你总是做完一件再去做另一件,不管是否需要时间等待,这就是同步;异步呢...原创 2014-03-14 17:01:06 · 130 阅读 · 0 评论 -
java并发(二十四)多线程结果组装
本文主要介绍多线程的结果组装。其中可以忽略2处代码创建线程池的区别,请关注其他的业务逻辑代码。全部代码已经在附件中上传。如有疑问,请跟帖留言,笔者会予以答复。信号量相比自旋锁的优点很多,性能、代码简单。自旋锁不停得sleep并唤醒,而信号量的底层采用了wait进行编程,只唤醒一次即可。因此性能优越许多。[img]http://dl2.iteye.com/upload/attachment/00...2014-03-24 22:01:19 · 582 阅读 · 0 评论 -
java并发(二十五)java7之fork-join框架
如果让我个人理解什么是fork-join,我立刻会想到hadoop的map/reduce。他们是同一种模型。更早之前,笔者就看过关于fork-join的相关文章,但是理解的都不够深刻。自从深入研究了java多线程这块的相关技术,再回头来看fork-join,觉得真是个了不起的技术。[b]概述[/b]fork/join框架是ExecutorService接口的一种具体实现,目的是为了帮助...2014-03-26 14:12:50 · 253 阅读 · 0 评论 -
java并发(二十六)正确使用Volatile变量
[size=xx-large]概述[/size]您只能在有限的一些情形下使用 volatile 变量替代锁。要使volatile变量提供理想的线程安全,必须同时满足下面两个条件:[list][*]对变量的写操作不依赖于当前值。[*]该变量没有包含在具有其他变量的不变式中。[/list]实际上,这些条件表明,可以被写入volatile变量的这些有效值独立于任何程序的状态,包括...原创 2014-03-30 19:41:06 · 198 阅读 · 0 评论 -
java并发(二十七) 并发性标注
[size=xx-large]一介绍[/size][code="xml"] net.jcip jcip-annotations 1.0[/code]注解包括下面的一些内容[img]http://dl2.iteye.com/upload/attachment/0095/8005/33f3fb09-4cc4-3cdd-b9b8-974a5649d6ad.jpg[/i...2014-04-07 10:49:23 · 222 阅读 · 0 评论 -
java并发(二十八)并发随机数,原子变量,并发集合
[size=xx-large]原子变量[/size] java.util.concurrent.atomic包定义了对单一变量进行原子操作的类。原子变量类提供了在整数或者对象引用上的细粒度原子操作(因此可伸缩性更高),并使用了现代处理器中提供的底层并发原语(例如比较并交换[compare-and-swap])。所有的类都提供了get和set方法,可以使用它们像读写volatile变量一样...原创 2014-04-13 12:04:48 · 262 阅读 · 0 评论 -
java并发(二十九)构建高效且可伸缩的结果缓存
[size=xx-large]概述[/size] 几乎所有应用程序,都会使用某种形式的缓存。重用之前的计算结果,能降低延时,提高吞吐量,但却要消耗更多的内存。用内存“换”CPU。缓存看上去非常简单,然而简单的缓存可能会将性能瓶颈装变为可伸缩性瓶颈,即使缓存是用于提升单线程的性能。笔者会循序渐进的介绍缓存的使用方法演进。[size=xx-large]模拟定义接口和功能[/size]...原创 2014-04-23 11:52:54 · 184 阅读 · 0 评论 -
java并发(三十三)栅栏CyclicBarrier
如果说CountDownLatch(闭锁)是一次性的,那么CyclicBarrier正好可以循环使用。它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point)。所谓屏障点就是一组任务执行完毕的时刻。 比如在性能测试的时候,多线程需要把数据源的连接准备好,然后执行数据库相关操作。那么“准备”这个任务就可以使用闭锁。 关键方法[cod...2015-09-12 16:09:00 · 184 阅读 · 0 评论 -
java并发(十五)Java中的锁
锁像synchronized同步块一样,是一种线程同步机制,但比Java中的synchronized同步块更复杂。因为锁(以及其它更高级的线程同步机制)是由synchronized同步块的方式实现的,所以我们还不能完全摆脱synchronized关键字(译者注:这说的是Java 5之前的情况)。自Java 5开始,java.util.concurrent.locks包中包含了一些锁的实现,...原创 2014-03-09 12:07:05 · 116 阅读 · 0 评论 -
java并发(十四)Slipped Conditions
所谓Slipped conditions,就是说, 从一个线程检查某一特定条件到该线程操作此条件期间,这个条件已经被其它线程改变,导致第一个线程在该条件上执行了错误的操作。这里有一个简单的例子:[code="java"]public class Lock { private boolean isLocked = true; public void lock() {...原创 2014-03-09 11:28:24 · 144 阅读 · 0 评论 -
java并发(三十)闭锁CountDownLatch
CountDownLatch,一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。主要方法public CountDownLatch(int count);构造方法参数指定了计数的次数public void countDown();countDown方法,当前线程调用此方法,则计数减一public void await() throws I...原创 2014-05-07 23:33:38 · 157 阅读 · 0 评论 -
java并发(三十一)Amdahl定律
[b]阿姆达尔定律[/b]阿姆达尔(Amdahl)定律是计算机系统设计的重要定量原理之一,于1967年由IBM360系列机的主要设计者阿姆达尔首先提出。该定律是指:系统中对某一部件采用更快执行方式所能获得的系统性能改进程度,取决于这种执行方式被使用的频率,或所占总执行时间的比例。阿姆达尔定律实际上定义了采取增强(加速)某部分功能处理的措施后可获得的性能改进或执行时间的加速比。简单来说是通过更快...2014-05-19 16:15:09 · 244 阅读 · 0 评论 -
java并发(三十二)非阻塞算法
如果在某算法中,一个线程的失败或挂起不会导致其他线程也失败挂起,那么这种算法就被称为非阻塞算法。 如果在算法的每个步骤中都存在某个线程能够执行下去,那么这种算法也被称为无锁算法(Lock-Free)。...2014-06-25 14:08:23 · 132 阅读 · 0 评论 -
java并发(一)介绍
单CPU:时间切片多核多线程CPU:真正的并行 如果一个线程在读一个内存时,另一个线程正向该内存进行写操作,那进行读操作的那个线程将获得什么结果呢?是写操作之前旧的值?还是写操作成功之后的新值?或是一半新一半旧的值?或者,如果是两个线程同时写同一个内存,在操作完成后将会是什么结果呢?是第一个线程写入的值?还是第二个线程写入的值?还是两个线程写入的一个混合值?因此如没有合适的预防措...原创 2014-03-03 21:12:28 · 142 阅读 · 0 评论 -
java并发(二)多线程的优点
尽管面临很多挑战,多线程有一些优点使得它一直被使用。这些优点是:[list][*]资源利用率更好[*]程序设计在某些情况下更简单[*]程序响应更快[/list][size=xx-large]资源利用率更好[/size]想象一下,一个应用程序需要从本地文件系统中读取和处理文件的情景。比方说,从磁盘读取一个文件需要5秒,处理一个文件需要2秒。处理两个文件则需要:5秒...原创 2014-03-03 21:28:08 · 100 阅读 · 0 评论 -
java并发(三)多线程的代价
从一个单线程的应用到一个多线程的应用并不仅仅带来好处,它也会有一些代价。不要仅仅为了使用多线程而使用多线程。而应该明确在使用多线程时能多来的好处比所付出的代价大的时候,才使用多线程。如果存在疑问,应该尝试测量一下应用程序的性能和响应能力,而不只是猜测。[size=xx-large]设计更复杂[/size]虽然有一些多线程应用程序比单线程的应用程序要简单,但其他的一般都更复杂。在多线程访问共...原创 2014-03-03 21:39:48 · 154 阅读 · 0 评论 -
java并发(四)如何创建并运行java线程
[size=xx-large]创建Thread的子类[/size]创建Thread子类的一个实例并重写run方法,run方法会在调用start()方法之后被执行。例子如下:[code="java"]public class MyThread extends Thread { public void run(){ System.out.println("MyThrea...原创 2014-03-03 21:48:52 · 197 阅读 · 0 评论 -
java并发(五)竞态条件与临界区
在同一程序中运行多个线程本身不会导致问题,问题在于多个线程访问了相同的资源。如,同一内存区(变量,数组,或对象)、系统(数据库,web services等)或文件。实际上,这些问题只有在一或多个线程向这些资源做了写操作时才有可能发生,只要资源没有发生变化,多个线程读取相同的资源就是安全的。多线程同时执行下面的代码可能会出错:[code="java"]public class Count...原创 2014-03-03 21:57:42 · 129 阅读 · 0 评论 -
java并发(六)线程安全与共享资源
允许被多个线程同时执行的代码称作线程安全的代码。线程安全的代码不包含竞态条件。当多个线程同时更新共享资源时会引发竞态条件。因此,了解Java线程执行时共享了什么资源很重要。[size=xx-large]局部变量[/size]局部变量存储在线程自己的栈中。也就是说,局部变量永远也不会被多个线程共享。所以,基础类型的局部变量是线程安全的。下面是基础类型的局部变量的一个例子:[code=...原创 2014-03-04 00:04:44 · 174 阅读 · 0 评论 -
java并发(七)线程安全及不可变性
当多个线程同时访问同一个资源,并且其中的一个或者多个线程对这个资源进行了写操作,才会产生竞态条件。多个线程同时读同一个资源不会产生竞态条件。我们可以通过创建不可变的共享对象来保证对象在线程间共享时不会被修改,从而实现线程安全。如下示例:[code="java"]public class ImmutableValue{ private int value = 0; p...原创 2014-03-04 00:05:13 · 121 阅读 · 0 评论 -
java并发(九)线程通信
线程通信的目标是使线程间能够互相发送信号。另一方面,线程通信使线程能够等待其他线程的信号。例如,线程B可以等待线程A的一个信号,这个信号会通知线程B数据已经准备好了。本文将讲解以下几个JAVA线程间通信的主题:1、通过共享对象通信2、忙等待3、wait(),notify()和notifyAll()4、丢失的信号5、假唤醒6、多线程等待相同信号7、不要对常量字符串或全...原创 2014-03-04 11:12:12 · 96 阅读 · 0 评论 -
java并发(十)死锁 & 活锁
活锁:一个线程通常会有会响应其他线程的活动。如果其他线程也会响应另一个线程的活动,那么就有可能发生活锁。同死锁一样,发生活锁的线程无法继续执行。然而线程并没有阻塞——他们在忙于响应对方无法恢复工作。这就相当于两个在走廊相遇的人:Alphonse向他自己的左边靠想让Gaston过去,而Gaston向他的右边靠想让Alphonse过去。可见他们阻塞了对方。Alphonse向他的右边靠,而Gaston向...原创 2014-03-05 07:52:26 · 237 阅读 · 0 评论 -
java并发(十一)避免死锁
在有些情况下死锁是可以避免的。本文将展示三种用于避免死锁的技术:加锁顺序加锁时限死锁检测[b]加锁顺序[/b]当多个线程需要相同的一些锁,但是按照不同的顺序加锁,死锁就很容易发生。如果能确保所有的线程都是按照相同的顺序获得锁,那么死锁就不会发生。看下面这个例子:Thread 1: lock A lock BThread 2:...原创 2014-03-05 09:35:14 · 120 阅读 · 0 评论 -
java并发(十二)饥饿和公平
如果一个线程因为CPU时间全部被其他线程抢走而得不到CPU运行时间,这种状态被称之为“饥饿”。而该线程被“饥饿致死”正是因为它得不到CPU运行时间的机会。解决饥饿的方案被称之为“公平性” – 即所有线程均能公平地获得运行机会。[b] 下面是本文讨论的主题:[/b]1. Java中导致饥饿的原因:高优先级线程吞噬所有的低优先级线程的CPU时间。线程被永久堵塞在一个等待进入...原创 2014-03-07 10:56:13 · 129 阅读 · 0 评论 -
java并发(十三)嵌套管程锁死
嵌套管程锁死类似于死锁, 下面是一个嵌套管程锁死的场景:[quote]线程1获得A对象的锁。线程1获得对象B的锁(同时持有对象A的锁)。线程1决定等待另一个线程的信号再继续。线程1调用B.wait(),从而释放了B对象上的锁,但仍然持有对象A的锁。线程2需要同时持有对象A和对象B的锁,才能向线程1发信号。线程2无法获得对象A上的锁,因为对象A上的锁当前正被线程1持有...原创 2014-03-07 15:59:00 · 115 阅读 · 0 评论 -
java并发(三十四)协程kilim
[size=xx-large]概述[/size]对协程的技术已经觊觎很久,他有高性能的优点,但目前工具对他支持的不是很好,调试繁琐。苦于运维和调试比较困难,一直望而却步。恰逢十一,决心攻下这块碉堡。这边文章只是个引子,后续会做更详细的描述,不断完善。贴出实践的经验。Java里成熟一点的框架属kilim,这个发音让我想起了俄罗斯的克林姆林宫。顺便欣赏下美景吧。[img]http:...2015-10-02 11:29:54 · 435 阅读 · 0 评论