1.Executor:
1).为什么会有Executor? 无限的创建线程会导致浪费很多的资源,线程频繁的挂起与唤醒都会影响性能。Executor就充当了线程池的一部分。
2).常见的线程池是Executors.newFixedThreadPool .它可以生产一个定长的线程池,当线程池中的线程不够用的时候就到生产一个线程直到达到额定的线程数。这时候线程的长度就不会再改变。还有例如newCacheThreadPool可以根据当前使用情况,回收空闲线程。还有例如:ScheduledThreadPool,这个线程池可以用来代替Timer。Timer有如下两个问题:一.如果执行耗时的任务,有可能出现同一个时间点应该执行两个或以上的任务,这时候其中一个或多个任务可能会丢失,或者被重复执行。二:如果上一个任务抛了运行时异常以后,后面的任务就丢失了。ScheduledThreadPool多线程定时执行,可解决以上两个问题
3).ExecutorService还能联合Future使用,使用Executor.submit(Callable xx) 然后返回一个Future 。
2.Future:
1).为什么要有Future?以往一个线程执行一个任务之后就无法知道该任务的状态,运行情况,更加不能停止该任务,例如这个任务已经不需要执行了,我们还不能把它停掉,白白浪费性能。Future提供查询任务的状态,是否完成,是否已取消,并且可以取消执行任务。并且额外还提供阻塞返回和定时阻塞返回。
2).典型的实现是FutureTask
3.CompleteService
1.为什么要用CompleteService?使用executorService.submit返回一个Future之后,可以一直循环判断Future是否完成,然后拿结果。更好的办法是使用CompleteService. CompleteService可以把已完成的Future放到一个BlockingQueue中,然后我们只管从中取Future就可以了。
4.BlockingQueue
1).为什么要使用BlockingQueue?一般的Queue如果take不到值就返回null.但是有时候我们想要他等待有结果的时候给我们返回。
2).BlockingQueue内部使用条件队列来实现。
5.HashTable和ConcurrentHashMap的一个重要区别于锁的粒度上面。HashTable使用内部锁保护了整一个容器而ConcurrentHashMap中的就采用了分离锁,分离出了16个锁,每个锁守护容器的一部分。分离锁的一个负面的效果是,如果想对容器独占锁,那么获取所有的锁,例如ConcurrentHashMap需要扩容,重排的,reHash的时候。
6.闭锁(Latch)与关卡(Barrier):一个闭锁工作起来就像一个大门,直到闭锁达到终点之前,门一直关着,没有线程能通过,在终点状态到来的时候,门开了,允许所有线程都通过。闭锁是一次性的使用的对象,一旦进入到最终状态,就不能被重置了。关卡(barrier)类似于闭锁。它们都能够阻塞一组线程,直到某个条件达到,闭锁等待的是事件,而关卡等待的是其他线程。其实闭锁和关卡都可以理解为一个计数器。
7.你可以将Thread Local<T> 看做map<Thread,T> 它存储了与线程相关的值,但是,事实上它并非是这样实现的,与线程相关的值存储在线程对象自身中,线程终止后,这些值会被垃圾回收
8.如何避免锁循环死锁:.如果多个线程用固定的秩序来获得锁就能避免“锁顺序死锁”问题。使用System.identityHashCode比较两个对象,根据比较的结果来固定访问锁的秩序,从而可以避免两个对象互相等待对方的锁的现象。
9.与单线程相比,使用多线程总会引入一些性能的开销,这些开销包括:与协调线程相关的开销(加锁,信号,内存同步),增加上下文切换,线程的创建和消亡,以及调度的开销。当线程被过度使用后,这些开销甚至会超过提高后的吞吐量响应性和计算能力带来的补偿。所以使用多线程的时候要注意减少这些开销。
10.Amdahl定律告诉我们,程序的可伸缩性是由串行执行的代码的比例决定的,(当处理器的个数为理想最大化的时候公式为1/F ,F为串行化比例)而串行代码大部分是由独占锁的,所以要提高可伸缩性,可以用以下方式:减少锁的竞争,减少锁的粒度,减少锁的持有时间,使用非独占锁(读写分离锁等)。
11.对象池对于并发应用来说不是一个好的选择,并发应用中多使用线程本地分配的块来取消共用对象堆中的同步,如果引入对象池,必然会涉及到对象池同步的问题,这便产生了线程阻塞的问题,其代价比直接分配的代价要大。
12.ReentrantLock 和Synchronized 有相同的作用,提供互斥锁和内存可见性。只有当需要使用到ReentrantLock的高级功能的时候才应该使用ReentrantLock否则使用Synchronized。高级功能包括:可定时的,可轮询的与可中断的获取锁操作,公平队列,或者非块结构的锁。内部锁相比显式锁的优势在于:内部锁使用起来更加简洁,并且使用ReentrantLock的时候,如果忘记在finally块中调用unlock,导致锁没有释放,可能会引起大问题,所以如果没有使用到ReentrantLock的高级功能应该使用Synchronized
13.ReentrantLock和Semaphore他们的实现都用到了同一个基类,AbstractQueueSynchronizer(AQS);其他还有CountDownLatch,ReentrantWriteReadLock,SynchronousQueue和FutureTask都扩展了这个类。AQS,它管理一个关于状态信息的单一整数,状态信息可以通过protected类型的getState,setState和compareAndSetState等方法进行操作。ReentrantLock用来表示拥有他的线程已经请求了多少次锁,Semaphore用它来表现剩余的许可数,FutureTask用它来表示任务状态(未开始,执行,完成,取消)。
14.什么时候使用内部条件队列,什么时候使用外部的条件队列?这个和ReentrantLock和Synchronized之间的选择是一样的,如果需要用到条件队列的一些高级特性的,例如,需要用到公平队列,或者让每个锁对应多个等待集。
15.java.util.concurrent 包中的许多类,比使用synchronized有更好的性能和伸缩性,提升的原始来源是:原子变量和非阻塞的同步机制。
java中加锁的语法比较简洁但是jvm和os管理锁的工作并不简单,加锁需要遍历JVM中整个复杂的代码路径,并可能引起系统级的加锁,线程挂起以及上下文切换。CAS(compare and swap)的性能更佳
1).CAS最重要的缺点是:他强迫调用者处理竞争(通过重试,回退,或者放弃);然而如果是使用锁,在锁被获得之前,却可以通过阻塞自动处理竞争。
2).即使是在“快速路径”(无竞争锁的路径)上,获取和释放无竞争锁的开销大约也是CAS的两倍。p324
非阻塞算法使用了低层级并发原语,比如比较并交换,取代了锁。原子变量类向用户提供了这些低层级原语,也能够当作‘更佳的volatile变量’使用。同时提供了整数类和对象引用的原子化更新操作。
16.重排序:JMM(java memory model)允许从不同的角度观看一个动作,此时该动作会以不同的次序执行,这种错序执行的现象称为重排序。JMM为所有程序内部的动作定义了一个关系,叫做happens-before。要想保证执行动作B的线程看到动作A的结果(无论A和B是否发生在同一个线程中),A和B之间就必须满足happens-before关系。如果两个操作之间未依照happens-before关系排序,JVM可以对它们随意排序。
分享到:
相关推荐
Java并发编程实践是Java...通过这些笔记,我们可以了解到Java并发编程中的关键概念和实践,对于理解和编写高效的并发代码具有极大的帮助。在实际开发中,需要根据具体需求灵活应用这些知识,以保证程序的稳定性和性能。
《JAVA并发编程实践》随着多核处理器的普及,使用并发成为构建高性能应用程序的关键。Java 5以及6在开发并发程序中取得了显著的进步,提高了Java虚拟机的性能以及并发类的可伸缩性,并加入了丰富的新并发构建块。在...
### Java并发编程实践笔记知识点详解 #### 一、保证线程安全的方法 1. **不要跨线程访问共享变量:** 当多个线程共享某个变量时,若其中一个线程修改了该变量,其他线程若没有正确同步,则可能读取到错误的数据。...
《JAVA并发编程实践》这本书是Java开发者深入理解并发编程的重要参考资料。它涵盖了Java并发的核心概念、工具和最佳实践,旨在帮助读者在多线程环境下编写高效、安全的代码。 并发编程是现代软件开发中的关键技能,...
《Java并发编程实践》是一本深入探讨Java多线程编程的经典著作,由Brian Goetz、Tim Peierls、Joshua Bloch、Joseph Bowles和David Holmes等专家共同编写。这本书全面介绍了Java平台上的并发编程技术,是Java开发...
《JAVA并发编程实践》随着多核处理器的普及,使用并发成为构建高性能应用程序的关键。Java 5以及6在开发并发程序中取得了显著的进步,提高了Java虚拟机的性能以及并发类的可伸缩性,并加入了丰富的新并发构建块。在...
Java并发编程实践笔记是一份关于Java并发编程的实践笔记,涵盖了多种关于线程安全、并发编程的实践经验和原则。下面是从笔记中总结的知识点: 1. 保证线程安全的三种方法:不要跨线程访问共享变量,使用final类型的...
《JAVA并发编程实践》既能够成为读者的理论支持,又可以作为构建可靠的、可伸缩的、可维护的并发程序的技术支持。《JAVA并发编程实践》并不仅仅提供并发API的清单及其机制,还提供了设计原则、模式和思想模型,使...
《JAVA并发编程实践》适合于具有一定Java编程经验的程序员、希望了解Java SE 5以及6在线程技术上的改进和新特性的程序员,以及Java和并发编程的爱好者。 作者简介 作者:(美)戈茨 等 本书作者系lava标准化组织...
Java并发编程实践.pdf 本文档讲述了Java并发编程实践,特别是使用开源软件Amino构建并发应用程序。Amino是一个开源软件,具有可操作性、跨平台性、无锁数据结构等特点,适用于多核操作系统。下面是本文档的知识点...
Java并发编程实践-电子书-01章.pdf Java并发编程实践-电子书-02章.pdf Java并发编程实践-电子书-03章.pdf Java并发编程实践-电子书-04章.pdf Java并发编程实践-电子书-05章.pdf Java并发编程实践-电子书-06章.pdf ...
《JAVA并发编程实践》这本书是Java开发者深入理解并发编程的重要参考资料。并发编程是现代软件开发中的核心主题,尤其是在多核处理器普及的今天,利用好并发能够显著提升程序的执行效率和系统性能。这本书以实践为...
### Java并发编程实践知识点详解 #### 一、Java并发编程基础 ##### 1.1 并发与并行概念区分 在Java并发编程实践中,首先需要理解“并发”与“并行”的区别。“并发”指的是多个任务同时进行,但实际上可能是在多...
综合来看,该书不仅适合于对Java并发编程感兴趣的初学者,同样也适合有经验的开发者,作为一本参考资料和实践指南,读者可以通过它来加深对Java并发特性的理解和应用。书中丰富的案例分析和代码示例将有助于读者更...
《Java并发编程实践》是关于Java语言在并发编程领域的实践指南,作者在本书中详细介绍了在Java编程中,如何高效地实现多线程程序的设计和开发。本书不仅为初学者提供了理论基础,还为有经验的开发者提供了优化并发...