自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(65)
  • 收藏
  • 关注

原创 39-性能与伸缩性

性能与伸缩性使用线程的一种说法是为了提高性能。多线程可以使程序充分利用闲置的资源,提高资源的利用率,同时能够并行处理任务,提高系统的响应性。 但是很显然,引入线程的同时也引入了系统的复杂性。另外系统的性能并不是总是随着线程数的增加而总是提高。性能的提升通常意味着可以用更少的资源做更多的事情。这里资源是包括我们常说的CPU周期、内存、网络带宽、磁盘IO、数据库、WEB服务等等。 引入多线程可...

2018-03-24 15:26:25 463

原创 38-死锁与活跃度

死锁与活跃度死锁前面谈了很多并发的特性和工具,但是大部分都是和锁有关的。我们使用锁来保证线程安全,但是这也会引起一些问题。锁顺序死锁(lock-ordering deadlock):多个线程试图通过不同的顺序获得多个相同的资源,则发生的循环锁依赖现象。动态的锁顺序死锁(Dynamic Lock Order Deadlocks):多个线程通过传递不同的锁造成的锁顺序死锁问题。资...

2018-03-24 15:21:47 280

原创 37-Java内存模型

Java内存模型Java内存模型即Java Memory Model,简称JMM。JMM定义了Java 虚拟机(JVM)在计算机内存(RAM)中的工作方式。JVM是整个计算机虚拟模型,所以JMM是隶属于JVM的。如果我们要想深入了解Java并发编程,就要先理解好Java内存模型。Java内存模型定义了多线程之间共享变量的可见性以及如何在需要的时候对共享变量进行同步。原始的Java内存模型效...

2018-03-24 15:20:17 324

原创 36-非阻塞算法

非阻塞算法在不只一个线程访问一个互斥的变量时,所有线程都必须使用同步,否则就可能会发生一些非常糟糕的事情。Java 语言中主要的同步手段就是 synchronized 关键字(也称为内置锁),它强制实行互斥,确保执行 synchronized 块的线程的动作,能够被后来执行受相同锁保护的 synchronized 块的其他线程看到。在使用得当的时候,内置锁可以让程序做到线程安全,但是在使用锁定...

2018-03-24 15:18:13 161

原创 35-CAS原理深度分析

CAS原理深度分析java.util.concurrent包完全建立在CAS之上的,没有CAS就不会有此包。可见CAS的重要性。CASCAS:Compare and Swap,翻译成比较并交换。 java.util.concurrent包中借助CAS实现了区别于synchronouse同步锁的一种乐观锁。本文先从CAS的应用说起,再深入原理解析。CAS应用CAS...

2018-03-24 15:16:26 290

原创 34-原子变量类

原子变量类从JDK1.5开始提供了java.util.concurrent.atomic包,方便程序员在多线程环境下,无锁的进行原子操作。原子变量的底层使用了处理器提供的原子指令,但是不同的CPU架构可能提供的原子指令不一样,也有可能需要某种形式的内部锁,所以该方法不能绝对保证线程不被阻塞。在Atomic包里一共有12个类,四种原子更新方式,分别是原子更新基本类型,原子更新数组,原子更新引...

2018-03-24 15:13:39 194

原创 33-ScheduledThreadPoolExecutor源码分析

ScheduledThreadPoolExecutor源码分析自JDK1.5开始,JDK提供了ScheduledThreadPoolExecutor类来支持周期性任务的调度。在这之前的实现需要依靠Timer和TimerTask或者其它第三方工具来完成。但Timer有不少的缺陷:Timer是单线程模式,如果在执行任务期间某个TimerTask耗时较久,那么就会影响其它任务的调度;Time...

2018-03-18 18:26:28 196

原创 32-DelayQueue

精巧好用之DelayQueueDelayQueue是一种无界的阻塞队列,队列里只允许放入可以”延期”的元素,队列中列头的元素是最先”到期”的元素。如果队列中没有任何元素”到期”,尽管队列中有元素,也不能从队列获取到任何元素。源码分析首先还是看一下内部数据结构:public class DelayQueue<E extends Delayed> extends Abs...

2018-03-18 18:25:54 169

原创 31-Timer的缺陷分析

Timer的缺陷分析Timer计时器可以定时(指定时间执行任务)、延迟(延迟5秒执行任务)、周期性地执行任务(每隔个1秒执行任务),但是,Timer存在一些缺陷:Timer在执行所有定时任务时只会创建一个线程。如果某个任务的执行时间长度大于其周期时间长度,那么就会导致这一次的任务还在执行,而下一个周期的任务已经需要开始执行了,当然在一个线程内这两个任务只能顺序执行,有两种情况:对于之前需...

2018-03-18 18:25:16 388

原创 30-Timer和TimerTask

Timer和TimerTaskTimer就是一个调度器,而TimerTask只是一个实现了run方法的类,而具体的TimerTask需要由你自己来实现,例如这样:Timer timer = new Timer();timer.schedule(new TimerTask() { public void run() { System.out.prin...

2018-03-18 18:24:39 181

原创 29-CompletionService和ExecutorCompletionService

CompletionService和ExecutorCompletionService《Java并发编程实战》一书6.3.5节CompletionService:Executor和BlockingQueue,有这样一段话: 如果向Executor提交了一组计算任务,并且希望在计算完成后获得结果,那么可以保留与每个任务关联的Future,然后反复使用get方法,同时将参数timeout指...

2018-03-18 18:24:01 188

原创 28-Callable、Future和FutureTask

Callable、Future和FutureTask在前面的文章中我们讲述了创建线程的2种方式,一种是直接继承Thread,另外一种就是实现Runnable接口。这2种方式都有一个缺陷就是:在执行完任务之后无法获取执行结果。如果需要获取执行结果,就必须通过共享变量或者使用线程通信的方式来达到效果,这样使用起来就比较麻烦。而自从Java 1.5开始,就提供了Callable和Future,通...

2018-03-18 18:23:37 110

原创 27-扩展ThreadPoolExecutor

扩展ThreadPoolExecutorThreadPoolExecutor是可扩展的,通过查看源码可以发现,它提供了几个可以在子类化中改写的方法:beforeExecute,afterExecute,terminated。源码片段如下所示:protected void beforeExecute(Thread t, Runnable r) { } protected void aft...

2018-03-18 18:23:02 161

原创 26-设置线程池的大小

设置线程池的大小线程池的理想大小取决于将要提交的任务类型和所部署系统的特性。为了正确的定制线程池的大小,你需要理解你的计算环境、资源预算和任务的自身特性。部署系统中安装了多少个CPU?多少内存?任务是计算密集型、I/O密集型还是二者皆可?它们是否需要像JDBC Connection这样的稀缺资源?如果你有不同类别的任务,它们拥有差别很大的行为,那么应该考虑使用多个不同的线程池,这样每个线程...

2018-03-18 18:22:28 601

原创 25-深入分析线程池

深入分析线程池在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题:如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统的效率,因为频繁创建线程和销毁线程需要时间。那么有没有一种办法使得线程可以复用,就是执行完一个任务,并不被销毁,而是可以继续执行其他的任务?在Java中可以通过线程池来达到...

2018-03-18 18:21:56 142

原创 24-AQS详解

AQS(AbstractQueuedSynchronizer)详解谈到并发,不得不谈ReentrantLock;而谈到ReentrantLock,不得不谈AbstractQueuedSynchronizer(AQS)!类如其名,抽象的队列式的同步器,AQS定义了一套多线程访问共享资源的同步器框架,许多同步类实现都依赖于它,如常用的ReentrantLock/Semaphore/CountD...

2018-03-18 18:21:16 131

原创 23-同步工具类之CountDownLatch、CyclicBarrier和Semaphore

同步工具类之CountDownLatch、CyclicBarrier和Semaphore在java 1.5中,提供了一些非常有用的辅助类来帮助我们进行并发编程,比如CountDownLatch,CyclicBarrier和Semaphore,今天我们就来学习一下这三个辅助类的用法。CountDownLatchCountDownLatch类位于java.util.concurrent...

2018-03-17 22:48:01 127

原创 22-ForkJoin框架

Fork/Join框架介绍什么是Fork/Join框架Fork/Join框架是Java7提供的一个用于并行执行任务的框架,是一个把大任务分割成若干个小任务,最终汇总每个小任务结果后得到大任务结果的框架。我们再通过Fork和Join这两个单词来理解下Fork/Join框架,Fork就是把一个大任务切分为若干子任务并行的执行,Join就是合并这些子任务的执行结果,最后得到这个大任务的结...

2018-03-17 22:46:41 141

原创 21-阻塞队列之SynchronousQueue

SynchronousQueue实现原理Java 6的并发编程包中的SynchronousQueue是一个没有数据缓冲的BlockingQueue,生产者线程对其的插入操作put必须等待消费者的移除操作take,反过来也一样。不像ArrayBlockingQueue或LinkedListBlockingQueue,SynchronousQueue内部并没有数据缓存空间,你不能调用peek(...

2018-03-17 22:45:40 228

原创 20-阻塞队列之LinkedBlockingQueue

阻塞队列之LinkedBlockingQueue在前面的文章中,已经对JDK中的BlockingQueue做了一个回顾,同时对ArrayBlockingQueue中的核心方法作了说明,而LinkedBlockingQueue作为JDK中BlockingQueue家族系列中一员,由于其作为固定大小线程池(Executors.newFixedThreadPool())底层所使用的阻塞队列,分析它的...

2018-03-17 22:44:05 400

原创 19-阻塞队列之ArrayBlockingQueue

Java中的阻塞队列什么是阻塞队列阻塞队列(BlockingQueue)是一个支持两个附加操作的队列。这两个附加的操作是:在队列为空时,获取元素的线程会等待队列变为非空。当队列满时,存储元素的线程会等待队列可用。阻塞队列常用于生产者和消费者的场景,生产者是往队列里添加元素的线程,消费者是从队列里拿元素的线程。阻塞队列就是生产者存放元素的容器,而消费者也只从容器里拿元素。Java...

2018-03-17 22:43:03 407

原创 18-并发容器之CopyOnWriteArrayList

并发容器之CopyOnWriteArrayListCopy-On-Write简称COW,是一种用于程序设计中的优化策略。其基本思路是,从一开始大家都在共享同一个内容,当某个人想要修改这个内容的时候,才会真正把内容Copy出去形成一个新的内容然后再改,这是一种延时懒惰策略。从JDK1.5开始Java并发包里提供了两个使用CopyOnWrite机制实现的并发容器,它们是:CopyOnWriteAr...

2018-03-17 22:40:59 150

原创 17-并发容器之ConcurrentHashMap

深入分析ConcurrentHashMapJDK5中添加了新的concurrent包,相对同步容器而言,并发容器通过一些机制改进了并发性能。因为同步容器将所有对容器状态的访问都串行化了,这样保证了线程的安全性,所以这种方法的代价就是严重降低了并发性,当多个线程竞争容器时,吞吐量严重降低。因此Java5.0开始针对多线程并发访问设计,提供了并发性能较好的并发容器,引入了java.util.con...

2018-03-17 22:35:21 284

原创 16-迭代器与ConcurrentModificationException

迭代器与ConcurrentModificationExceptionVector、ArrayList在迭代的时候如果同时对其进行修改就会抛出ConcurrentModificationException异常。下面我们就来讨论以下这个异常出现的原因以及解决办法。无论是直接迭代还是在Java5.0引入的for-each循环语法中,对容器类进行迭代的标准方式都是使用Iterator。然而,如果...

2018-03-17 22:33:58 217

原创 15-同步容器

同步容器为什么会出现同步容器在Java的集合框架中,主要有四大类别:List、Set、Queue、Map。List、Set、Queue接口分别继承了Collection接口,Map本身是一个接口。注意Collection和Map是一个顶层接口,而List、Set、Queue则继承了Collection接口,分别代表数组、集合和队列这三大类容器。像ArrayList、LinkedLi...

2018-03-17 22:32:15 109

原创 14-ThreadLocal类详细剖析

ThreadLocal类详细剖析对ThreadLocal的理解JDK中的源码是这样描述ThreadLocal的: This class provides thread-local variables. These variables differ from their normal counterparts in that each thread that accesses o...

2018-03-17 22:30:55 144

原创 13-线程间的通信与生产者消费者模型

线程间的通信与生产者消费者模型在前面我们讲了很多关于同步的问题,然而在现实中,需要线程之间的协作。比如说最经典的生产者-消费者模型:当队列满时,生产者需要等待队列有空间才能继续往里面放入商品,而在等待的期间内,生产者必须释放对临界资源(即队列)的占用权。因为生产者如果不释放对临界资源的占用权,那么消费者就无法消费队列中的商品,就不会让队列有空间,那么生产者就会一直无限等待下去。因此,一般情况下,当队

2018-02-04 23:40:48 177

原创 12-volatile关键字使用场景

volatile关键字使用场景Java 语言中的 volatile 变量可以被看作是一种 “程度较轻的 synchronized”;与 synchronized 块相比,volatile 变量所需的编码较少,并且运行时开销也较少,但是它所能实现的功能也仅是 synchronized 的一部分。本文介绍了几种有效使用 volatile 变量的模式,并强调了几种不适合使用 volatile 变量的情形。

2018-02-04 23:40:11 2656

原创 11-深入理解volatile关键字

深入理解volatile关键字我们对volatile这个关键字一定不陌生,或许也都用过。在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果。在Java 5之后,volatile关键字才得以重获生机。volatile关键字虽然从字面上理解起来比较简单,但是要用好不是一件容易的事情。由于volatile关键字是与Java的内存模型有关的,因此在讲述volatile关

2018-02-04 23:39:37 323 1

原创 10-同步机制的其它作用

同步机制的其它作用:原子性、可见性和有序性synchronized和Lock不仅可以确保原子性、可见性还可以确保有序性。在并发编程中,我们通常会遇到以下三个问题:原子性问题,可见性问题,有序性问题。我们先具体看一下这三个概念:原子性同步代码块和同步方法可以确保以原子的方式执行操作。原子是世界上的最小单位,具有不可分割性。比如 a=0;(a非long和double类型) 这个操作是不可分割的,那么我们

2018-02-04 23:39:12 495

原创 9-Lock显式锁

Lock显式锁在Java 5.0之前,在协调对共享对象的访问时可以使用的机制只有synchronized和volatile。Java 5.0增加了一种新的机制:Lock。与之前提到过的机制相反,Lock并不是一种替代内置加锁的方法,而是当内置加锁机制不适用时,作为一种可选择的高级功能。synchronized的缺陷synchronized是java中的一个关键字,也就是Java语言内置的特性。那么为

2018-02-04 23:38:55 164

原创 8-synchronized同步机制详解

synchronized 同步机制详解虽然多线程编程极大地提高了效率,但是也会带来一定的隐患。比如说两个线程同时往一个数据库表中插入不重复的数据,就可能会导致数据库中插入了相同的数据。今天我们就来一起讨论下线程安全问题,以及Java中提供了什么机制来解决线程安全问题。什么是线程安全性要对线程安全性给出一个确切的定义是非常复杂的。在线程安全性的定义中,最核心的概念就是正确性。如果对线程安全性的定义是模

2018-02-04 23:38:32 307

原创 7-守护线程

守护线程有时候,你希望创建一个线程来执行一些辅助工作,但又不希望这个线程阻碍JVM的关闭。在这种情况下就需要使用守护线程(Daemon Thread)。线程可分为两种:普通线程和守护线程。在JVM启动时创建的所有线程中,除了主线程以外,其它的线程都是守护线程(例如垃圾回收器以及其它执行辅助工作的线程)。当创建一个新线程时,新线程将继承创建它的线程的守护状态。因此在默认情况下,主线程创建的所有线程都是

2018-02-04 23:38:13 185

原创 6-线程泄漏

线程泄漏当单线程的控制台程序由于发生了一个未捕获的异常而终止时,程序将停止运行,并产生与程序正常输出非常不同的栈追踪信息,这与典型的程序输出不同,当一个程序发生了异常说明有不稳定的因素存在。如果在并发程序中线程失败就没那么容易发现了。栈追踪可能会从控制台输出,但是没有人会一直在看控制台,并且,当线程失败的时候,应用程序可能看起来仍在工作。就象程序能跑在50个线程的线程池上,也能够跑在49个线程的线程

2018-02-04 23:37:53 758

原创 5-线程的中断

线程的中断使用interrupt()中断线程当一个线程运行时,另一个线程可以调用对应的Thread对象的interrupt()方法来中断它,该方法只是在目标线程中设置一个标志,表示它已经被中断,并立即返回。这里需要注意的是,如果只是单纯的调用interrupt()方法,线程并没有实际被中断,会继续往下执行。下面一段代码演示了休眠线程的中断:public class SleepInterrupt im

2018-02-04 23:36:21 186

原创 Java集合框架

Java集合框架概述Java集合工具包位于Java.util包下,包含了很多常用的数据结构,如数组、链表、栈、队列、集合、哈希表等。学习Java集合框架下大致可以分为如下五个部分:List列表、Set集合、Map映射、迭代器(Iterator、Enumeration)、工具类(Arrays、Collections)。Java集合类的整体框架如下:从上图中可以看出,集合类主要分为两大类:Collect

2017-12-13 18:59:20 277

原创 缓存淘汰算法——LRU算法

缓存淘汰算法——LRU算法LRU原理LRU(Least recently used,最近最少使用)算法根据数据的历史访问记录来进行淘汰数据,其核心思想是“如果数据最近被访问过,那么将来被访问的几率也更高”。实现最常见的实现是使用一个链表保存缓存数据,详细算法实现如下:新数据插入到链表头部;每当缓存命中(即缓存数据被访问),则将数据移到链表头部;当链表满的时候,将链表尾部的数据丢弃。分析命中率

2017-12-09 00:31:45 283

原创 4-Thread类详解以及线程状态分析

Thread类详解线程的状态在正式学习Thread类中的具体方法之前,我们先来了解一下线程有哪些状态,这个将会有助于后面对Thread类中的方法的理解。线程从创建到最终的消亡,要经历若干个状态。一般来说,线程包括以下这几个状态:创建(new)、就绪(runnable)、运行(running)、阻塞(blocked)、time waiting、waiting、消亡(dead)。当需要新起一个线程来执行

2017-12-09 00:24:12 388

原创 3-Java中如何创建线程

Runnable和Thread实现多线程的区别Java中实现多线程有两种方法:继承Thread类、实现Runnable接口,在程序开发中只要是多线程,肯定永远以实现Runnable接口为主,因为实现Runnable接口相比继承Thread类有如下优势:可以避免由于Java的单继承特性而带来的局限;增强程序的健壮性,代码能够被多个线程共享,代码与数据是独立的;适合多个相同程序代码的线程去处理同一

2017-12-09 00:19:16 971

原创 2-Java中如何创建进程

Java中如何创建进程在Java中,可以通过两种方式来创建进程,总共涉及到5个主要的类。第一种方式是通过Runtime.exec()方法来创建一个进程,第二种方法是通过ProcessBuilder的start()方法来创建进程。下面就来讲一讲这2种方式的区别和联系。首先要讲的是Process类,Process类是一个抽象类,在它里面主要有几个抽象的方法,这个可以通过查看Process类的源代码得知:

2017-12-09 00:16:55 507

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除