2015.6.11(java并发续)

  1. 线程池执行线程任务的步骤:

    1) 调用Executors类的静态工厂方法创建一个ExecutorService对象,该对象代表一个线程池;

    2) 创建Runnable实现类或Callable实现类的实例,作为线程执行任务;

    3) 调用ExecutorServer对象的submit方法提交Runnable实例或Callable实例;

    4) 当不再提交任何任务时,调用ExecutorService对象的Shutdown方法来关闭线程池。

  2. Java8新增的线程池方法:

    1) ExecutorService newWorkStealingPool(int parallelist):创建持有足够线程的线程池来支持给定的并行级别,该方法还会使用多个队列来减少竞争;

    2) ExecutorService newWorkStealingPool():该方法可以看做是前一个方法的简本,并行级别不需要用户手工指定,是根据计算机CPU个数自动生成的,如果当前机器有6个CPU,则调用该方法时并行级别被设为6。

    Java8在线程支持上增加了利用多CPU并行的能力,以更好地发挥底层硬件的性能,这两个方法生成的work stealing池,都相当于后台线程池,如果所有的前台线程都死亡了,work stealig池中的线程也会自动死亡。

  3. Java8扩展的ForkJoinPool功能:

    Java8除了继续支持早期版本中的ForkJoinPoll(int parallelism)和ForkJoinPoll()两个方法外,还扩展了ForkJoinPoll的功能,增加了下面两个方法:

    1) ForkJoinPoll commonPool():该方法返回一个通用池,通用池的运行状态不受shutDown()或shutdownNow()方法的影响。但如果程序直接调用System.exit(0)来终止虚拟机,通用池以及通用池中正在执行的任务都会被自动终止;

    2) int getCommonPollParallelism():该方法返回通用池的并行级别。

  4. 线程安全工具类ThreadLocal和同步机制的区别:

    ThreadLocal是将需要并发访问的对象复制多份,每个线程拥有独立的一份资源,在编写多线程代码时,可以将不安全的整个变量封装进ThreaLocal,或者将与访问对象相关的状态使用ThreadLocal保存,用以保证安全。

    同步机制是通过对象加锁来实现多个线程对同一变量的访问安全的,该变量为多个线程共享,需要我们分析什么时候对变量进行读写,什么时候需要锁定对象,什么时候释放对该对象的加锁等。在这个过程中,程序并没有将资源(变量)复制多份,只是采用了安全机制来控制对这份资源的访问。

    ThreadLocal不能替代同步机制,两者所对应的解决方案不同。同步机制是为了同步多个线程对相同资源的访问,是多个线程之间进行通信的方式,而ThreadLocal是为了隔离多个线程的数据共享,从根本上避免多个线程之间对共享资源的竞争。

  5. Map对象线程安全和同步:

    昨天的日报提到了网页即时聊天信息保存在Map对象中,如何保证线程安全。下面讲几种实现方式,有理解的不对的地方,恳请各位师兄批评指正:

    1) 对非线程安全的HashMap对象加锁,采用采用Copy On Write机制:

    当我们读取Map的时候,直接读取,不需要同步。当我们修改数据的时候,我们就把当前数据Copy一份副本,然后在这个副本上进行修改,完成之后,再用修改后的副本,替换掉原来的数据,修改过程应该加锁,用来保证数据一致,关键代码如下:

这种方式虽然可以保证线程安全和数据一致,读的效率不受影响,但写的效率太低,适合用于高频率读低频率写的场景。

2) 线程安全的HashTable对象:

HashTable可以说是多线程环境下的HashMap,它除了线程安全这个特性之外,其余特点几乎与HashMap一样,所以高版本(>JDK1.5)的Java中一般不选择使用HashTable这话中数据类型。

3) 线程安全的ConcurrentHashMap对象:

之所以多线程环境下选择使用ConcurrentHashMap而不选择HashTable的原因是,线程对HashTable的加锁是独占式的,即同时只允许一个线程对HashTable加写锁,写的效率大大降低,而ConcurrentHashMap的加锁机制有别于HashTable:

ConcurrentHashMap将hash表分为16个桶(默认值),诸如put,remove等常用写操作只锁当前需要用到的桶,原来只能一个线程进入,现在能同时有16个写线程进入(写线程才需要锁定,而读线程几乎不受限制),相对于HashTable而言,ConcurrentHashMap并发性的提升是显而易见的。

所以,昨天提到的问题就可以用ConcurrentHashMap来完美解决,既能保证写效率的提升,又不影响读取效率。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-07-30 22:51:33

2015.6.11(java并发续)的相关文章

java并发编程之美-阅读记录11

java并发编程实践 11.1ArrayBlockingQueue的使用 有关logback异步日志打印中的ArrayBlockingQueue的使用 1.异步日志打印模型概述 在高并发.高流量并且响应时间要求比较小的系统中同步打印日志在性能上已经满足不了了,这是以因为打印本身是需要写磁盘的,写磁盘操作会暂时阻塞调用打印日志的业务系统,这会造成调用线程的响应时间增加.    ----- >>> 异步日志打印,是将打印日志任务放入一个队列后就返回,然后使用一个线程专门从队列中获取日志任务,

java并发编程11.原子变量与非阻塞同步机制

在非阻塞算法中不存在死锁和其他活跃性问题. 在基于锁的算法中,如果一个线程在休眠或自旋的同时持有一个锁,那么其他线程都无法执行下去,而非阻塞算法不会受到单个线程失败的影响. 锁的劣势 许多JVM都对非竞争锁获取和释放操作进行了极大的优化,但如果有多个线程同时请求锁,那么JVM就需要借助操作系统地功能.如果出现了这种情况,那么一些线程将被挂起并且在稍后恢复运行.当线程恢复执行时,必须等待其他线程执行完它们的时间片以后,才能被调度执行.在挂起和恢复线程等过程中存在着很大的开销,并且通常存在着较大时间

2015.6.10(java并发)

今天复习熟悉了Java并发的一些概念. 程序:系统要完成的一个任务,就是一个程序: 进程:每个运行中的程序就是一个进程,Windows任务管理器上可以看到每一个进程,Linux下使用ps –e命令可以查看当前运行的所有进程: 线程:每个运行的程序(进程)内部可能会包含多个顺序执行流,每个执行流就可以看做线程. 1. 进程的特性: 1) 独立性:进程是系统中独立存在的实体,它可以拥有自己独立的资源,每个进程都拥有自己私有的地址空间,其他进程不能访问这个进程空间内的数据. 2) 动态性:进程与程序的

Java并发安全部分知识点总结 —— 8月20日学习分享

非常感谢洋哥的本周知识分享,灰常精辟-!洋哥的知识串起来了线程安全的大部分知识,我也根据我的知识储备及网络搜寻,整理了一份我自己当前的理解. 一. 线程安全性的知识准备 1.1 知识准备a:JVM 内存模型 与 线程安全 线程安全,就是通过多个线程对某个资源进行有序访问或者修改,这里的某项资源对应的底层即是一个个的 JVM 内存模型. 所以,针对 线程安全 来谈的 JVM 内存模型,想要实现线程安全,那么就要实现两点:可见性及有序性,前者保证某项线程修改某共享变量之后可以被其它线程感知,后者保证

Java并发编程:Callable、Future和FutureTask(转)

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

6、Java并发编程:volatile关键字解析

Java并发编程:volatile关键字解析 volatile这个关键字可能很多朋友都听说过,或许也都用过.在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果.在Java 5之后,volatile关键字才得以重获生机. volatile关键字虽然从字面上理解起来比较简单,但是要用好不是一件容易的事情.由于volatile关键字是与Java的内存模型有关的,因此在讲述volatile关键之前,我们先来了解一下与内存模型相关的概念和知识,然后分析了volatil

7、Java并发编程:深入剖析ThreadLocal

Java并发编程:深入剖析ThreadLocal 想必很多朋友对ThreadLocal并不陌生,今天我们就来一起探讨下ThreadLocal的使用方法和实现原理.首先,本文先谈一下对ThreadLocal的理解,然后根据ThreadLocal类的源码分析了其实现原理和使用需要注意的地方,最后给出了两个应用场景. 以下是本文目录大纲: 一.对ThreadLocal的理解 二.深入解析ThreadLocal类 三.ThreadLocal的应用场景 若有不正之处请多多谅解,并欢迎批评指正. 请尊重作者

JAVA并发总结-基础篇

多线程 1. java中有几种方法可以实现一个线程? 继承Thread类,实现Runnable接口创建一个线程的唯一方法是实例化java.lang.Thread类(或其子类),并调用其start()方法 2. 如何停止一个正在运行的线程? 调用ThreadInstanceA.inerrupt()方法,这样当A线程在Thread的sleep,join方法,或者Object的wait方法的时候会直接抛出InerruptedException,捕捉后便可退出. public void shutdown

Java并发编程:线程的同步

.title { text-align: center } .todo { font-family: monospace; color: red } .done { color: green } .tag { background-color: #eee; font-family: monospace; padding: 2px; font-size: 80%; font-weight: normal } .timestamp { color: #bebebe } .timestamp-kwd