Java并发
文章平均质量分 80
义臻
你可以通过知乎ID找到我:义臻
转摘文章请注明出处。
展开
-
JAVA并发-显式锁(二)
在上一篇博客《JAVA并发-显式锁(一)》中介绍了Lock和ReadWriteLock的基本用法,下面来看看如何使用Lock的tryLock()方法来避免死锁。在博客《JAVA并发-3种典型的死锁》中有一个动态的锁顺序死锁。我们使用System.identifyHashCode()来固定线程获取锁的顺序,从而解决了死锁问题。学习了Lock之后,可以使用tryLock()来解决动态的锁顺序死锁问题。...原创 2016-08-11 14:14:43 · 396 阅读 · 0 评论 -
JAVA并发-条件队列
在JVM系列博客http://yizhenn.iteye.com/blog/2290864中讲过,Java语言的同步机制在底层实现上只有两种手段:"互斥"和"协同".体现在Java语言层面上,就是内置锁和内置条件队列.内置锁即synchronized,这个相关的博客有很多,不再多讲.内置条件队列这个词大家或许没有听过,他指的是Object.wait(),Object.notify(),Object...原创 2016-08-11 14:15:25 · 2989 阅读 · 0 评论 -
JAVA并发-中断处理和任务取消
中断处理在java程序中,当使用Thread.sleep()或者BlockingQueue.take()等阻塞方法时,需要处理InterruptedException。对于这种异常,通常有2种方案进行处理。1. 传递异常:将异常传递给方法的调用者。示例如下:BlockingQueue queue;public String getNextString() throws Interrupt原创 2016-08-11 14:15:16 · 665 阅读 · 0 评论 -
JAVA并发-3种典型的死锁
在JAVA并发编程中,我们使用锁来确保可变共享变量的安全性。要注意的是,不正确的使用锁很容易导致死锁。死锁的4个必要条件:1. 互斥访问2. 非抢占3. 持有并等待4. 循环等待在JAVA编程中,有3种典型的死锁类型:静态的锁顺序死锁,动态的锁顺序死锁,协作对象之间发生的死锁。静态的锁顺序死锁:a和b两个方法都需要获得A锁和B锁。一个线程执行a方法且已经获得了A锁,在等待B锁;另一个线...原创 2016-08-11 14:14:16 · 1911 阅读 · 0 评论 -
JAVA并发-DCL与JMM
首先必须声明,在volatile出现之前,错误的DCL代码如下。在volatile出现之后,正确的DCL代码如下。代码如下://错误的代码public class Singleton { private static Singleton instance=null; private Singleton(){} public static Singleton getInstance()...原创 2016-08-11 14:11:41 · 1589 阅读 · 0 评论 -
线程安全性的文档化
首先说一个错误的观点是“只要是加了synchronized关键字的方法或者代码块就一定是线程安全的,而没有加这个关键字的代码就不是线程安全的”。这种观点认为“线程安全要么全有要么全无”,事实上这是错误的。因为线程安全包含了几种级别:不可变的(Immutable):类的实例不可变(不可变类),一定线程安全,如String、Long、BigInteger等。无条件的线程安全(Unconditi原创 2017-04-18 09:50:15 · 2454 阅读 · 0 评论 -
变量的延迟初始化
在绝大多数的系统中,我们都会使用正常的初始化。正常的初始化代码是这样的:private final MyClass field = new MyCLass();但在有些程序中,我们不希望某些变量在正常的类加载过程中就被初始化。换言之,我们希望某些变量能够延迟初始化。在阅读下面的内容之前,笔者希望你能读一下我的另外一篇文章,单例模式的5种JAVA实现。你要问我为什么?答案只有四个字,“见多识广”!本...原创 2017-04-19 19:35:19 · 755 阅读 · 0 评论 -
JAVA并发-线程状态和线程组
在Java中,线程有6种基本状态,理解这6种基本状态之间的关系可以让我们对多线程有更好的理解.如下图所示:在Java中,所有的线程都存在于线程组中,每个线程组中可以包含多个线程或者线程组.运行下面的程序,从结果中可以看出默认的线程组层次结构.system是Java中的根线程组.从system开始,有一层层的线程和线程组.类似目录结构./** * Java线程组的结构,见运行结果原创 2016-08-11 14:15:51 · 494 阅读 · 0 评论 -
一个测试任务并发执行时间的方法
import java.util.concurrent.CountDownLatch;import java.util.concurrent.Executor;/** * Created by xuyizhen on 2017/4/16. */public class Util { /** * 测试任务task在指定的线程池execurtor中的并发度与性能的关系原创 2017-04-16 17:53:07 · 2418 阅读 · 0 评论 -
处理Callable线程内部的非受检异常
之前的博客中介绍过Runnable类线程的异常处理,数据JAVA多线程的童鞋应该知道。Java中处理Thread和Runnable线程体系之外,还用著名的Executor和Callable线程体系。而且,后者在实际中更为常见。那么在Runnable中奏效的UncaughtExceptionHandler机制在Callable中时候仍然有效呢?我们用代码来验证一下。 import j...原创 2017-04-22 18:42:28 · 3601 阅读 · 1 评论 -
UncaughtExceptionHandler—处理Runnable线程内的非受检异常
Java的异常非为受检异常和非受检异常。由于在多线程中,run()方法无法继续向上显式抛出异常。所以这就使得Thread线程中的异常处理变得棘手。首先对于受检异常,其应对办法非常通用:就是直接在run()方法体中捕获异常,然后进行对应的处理。对于非受检异常,JVM会帮助我们捕获到。那么我们如何处理JVM捕获的异常呢?答案是Thread.UncaughtExceptionHandler类。正如JDK文档所介绍的一样:“当一个线程由于发生了非受检异常而终止时,JVM会使用Thread.gerUncaugh原创 2017-04-21 10:54:13 · 5356 阅读 · 1 评论 -
JUC之CAS
JUC是java.util.concurrent包的简称,该包提供了并发编程的解决方案(当然,JAVA并发编程的解决方案还有synchronized)。从概括的层面来说,JUC包有两大核心:CAS和AQS。其中CAS是java.util.concurrent.atomic包的基础,AQS是java.util.concurrent.locks包以及一些常用类比如Semophore等类的基础。我们先来原创 2016-08-11 14:16:09 · 1347 阅读 · 0 评论 -
JUC之AQS
AQS是同步框架,它进行两个方面的工作:资源的管理和资源申请者的管理。对应由两部分组成:一个volatile int state(代表共享资源)和一个FIFO线程等待队列(多线程争用资源被阻塞时会进入此队列)。state的访问方式有三种: getState() setState() compareAndSetState()AQS定义两种资源共享方式:Exclusive(独占,只有原创 2016-08-11 14:16:18 · 962 阅读 · 0 评论 -
JAVA并发-显式锁(一)
JAVA语言除了提供内置锁synchronized,还在JDK6之后提供了高级的显式锁Lock作为功能上的补充。在大多数情况下,内置锁都能很好的工作,我们也尽量使用内置锁。但必须承认的是,内置锁存在一些局限性。比如:无法中断一个正在等待获取锁的线程;无法在请求一个锁时无限等待下去;无法实现非阻塞的加锁规则。当程序中需要这些高级的功能时,考虑使用显式锁。我们来介绍2种显示锁,Lock和ReadWri...原创 2016-08-11 14:14:33 · 310 阅读 · 0 评论 -
JAVA并发-减少锁的竞争
降低锁的竞争可以提高并发程序的性能和可伸缩性,有3种方式可以降低锁的竞争:1. 减少锁的持有时间(缩小锁的范围)2. 降低锁的请求频率(降低锁的粒度)3. 放弃使用独占锁,使用并发容器,原子变量,读写锁等等来代替它。减少锁的持有时间(减小锁的范围):减少锁的持有时间实际上就是减小锁的控制范围,将一些并不需要锁的操作从同步代码块中移除。如下所示,需要进行同步操作的只有attributes.get(k...原创 2016-08-11 14:14:24 · 287 阅读 · 0 评论 -
JAVA并发-ThreadPoolExecutor线程池的使用
在博客JAVA并发-Executor任务执行框架中曾说过,Executors有4种工厂方法,即newFixedThreadPool,newCachedThreadPool,newSingleThreadExecutor,newScheduledThreadPool。这些工厂方法其实都是创建了一些不同执行策略的ThreadPoolExecutor。我们可以创建自定义执行策略的ThreadPool原创 2016-08-11 14:14:07 · 929 阅读 · 0 评论 -
JAVA并发-Executor任务执行框架
首先介绍两个重要的接口,Executor和ExecutorService,定义如下:public interface Executor { void execute(Runnable command);}public interface ExecutorService extends Executor { //不再接受新任务,待所有任务执行完毕后关闭Executor原创 2016-08-11 14:13:57 · 504 阅读 · 0 评论 -
JAVA并发- 典型连接池的实现
package com.xyz.connpool;public interface IConnection { /** * 关闭当前连接 */ public void close(); /** * 销毁当前连接 */ public void destroy(); //应该具备的其他方法} public class Connection i...原创 2016-08-11 14:11:24 · 1034 阅读 · 0 评论 -
JAVA并发-并发编程常用类
在讲同步工具类之前,笔者想先介绍一下Runnable,Callable,Future,Executor,FutureTask这几个类或接口。1 Runnable和Callable是接口,实现两者的任何一个可以开发多线程。但是前者无法返回线程的执行结果,后者可以返回线程的执行结果。2 Future是一个接口,用于等待或者查看Callable线程的返回结果。3 Executor是线程的调度容器。...原创 2016-08-11 14:09:34 · 284 阅读 · 0 评论 -
JAVA并发-同步容器和并发容器
常见的同步容器类包括Vector和HashTable,以及Collections.synchronizedXxx()等工厂方法。这些类实现线程安全的方式是:将他们的可变成员变量封装起来,并对每个方法都进行同步,使得每次仅仅有一个线程能访问这些可变的成员变量。尽管这些类的方法都是同步的,但当并发访问多个方法的时候,还是有可能出错。比如,有两个线程,一个执行同步的get方法,一个执行同步的remove原创 2016-08-11 14:09:25 · 304 阅读 · 0 评论 -
JAVA并发-开发线程安全类
我们知道,面向对象的三大特征之一是封装。封装是指将一个对象A放到另一个对象B的内部,A作为B的成员变量,要想访问对象A只能通过对象B提供的方法。当把一个对象进行了封装之后,我们更容易分析客户代码对该对象的访问方式。如果将对象封装和加锁机制联合起来,就可以确保以线程安全的方式来使用非线程安全的对象。比如下面代码:@ThreadSafepublic class StringSet{原创 2016-08-11 14:09:17 · 225 阅读 · 0 评论 -
JAVA并发-为现有的线程安全类添加原子方法
JAVA中有许多线程安全的基础模块类,一般情况下,这些基础模块类能满足我们需要的所有操作,但更多时候,他们并不能满足我们所有的需要。此时,我们需要想办法在不破坏已有的线程安全类的基础上添加一个新的原子操作。有如下4中方案:1 修改类的源码,以添加新的原子操作2 继承该线程安全类,并添加原子操作3 使用客户端加锁方式4 使用组合方式(推荐)一般来讲,修改源码的方式不太可行,这样会破坏原有类原创 2016-08-11 14:09:08 · 581 阅读 · 0 评论 -
JAVA并发-从缓存一致性说volatile
学过计算机组成原理的一定知道,为了解决内存速度跟不上CPU速度这个问题,在CPU的设计中加入了缓存机制,缓存的速度介于CPU和主存之间。在进行运算的时候,CPU将需要的数据映射一份在缓存中,然后直接操作位于缓存中的数据,操作完毕后再将缓存中的数据写回到主存。这在单线程环境中是没有任何问题的。但是在多线程环境中就大不同了。假设现在有这样的一个场景:有两个线程thread1和thread2,他们都在...原创 2016-08-11 14:08:59 · 3295 阅读 · 5 评论 -
JAVA并发-内置锁和ThreadLocal
上一篇博客讲过,当多个线程访问共享的可变变量的时候,可以使用锁来进行线程同步。那么如果线程安全性存在的3个前提条件不同时存在的话,自然就不需要考虑线程安全性了。或者说如果我们能够将某个共享变量变为局部变量,那么自然线程安全性问题就不存在了。我们把“诸如将全局变量变为局部变量”这种将某个对象封闭在一个线程中的技术称为线程封闭,在《JAVA并发编程实践》中是这样说的,这么说有一定道理。但我还是想说说...原创 2016-08-11 14:08:48 · 1314 阅读 · 0 评论 -
JAVA并发-并发编程概述
不知道各位童鞋是否干过在程序主进程中嵌入IO操作这样“任性”的事情,笔者曾经干过,而且那时候还觉得自己很棒。没办法,那时候还年轻啊。后来随着学习的深入,知道了有nio这种神一样的东西。但如果有其他方案,至少笔者是不会使用nio这个类的。毕竟程序的易读性还是很重要滴。多数时候,我们完全可以使用多线程和IO阻塞来代替非阻塞IO。最近读了下经典《Java并发编程实践》,大师的书的确很棒,好了不说废话了,...原创 2016-08-11 14:08:38 · 304 阅读 · 0 评论 -
学习Java,我建议这样做
很多同学向我邀答,想要学习Java,却不知道该学什么,也不知道该学到什么深度?也有些外包的同学,想在技术上提升,却不知怎么做?本次 Live专为想学习和提高Java的人定制,给出了详细的学习路线,适合想要系统的专业的学习Java的人。尤其是:想要从事Java开发工作的大学生,想要转行当Java程序员的在职人员,想要提升Java水平却不知如何入手的小白等。30天从入门到精通? 那是宣传的...原创 2018-01-04 20:10:23 · 1087 阅读 · 2 评论