java多线程(二)

一、ThreadLocal:线程局部变量,是一种多线程间并发访问变量的解决方案。与其synchronized等枷锁的方式不同,ThreadLocal完全不提供锁,而是以空间换时间的手段,为每个线程提供变量的独立副本,以保障线程安全。从性能上说,ThreadLocal不具备绝对的优势,在并发不是很高的时候,枷锁的性能会更好,但作为一套与锁完全无关的线程解决方案,在高并发量或者竞争激烈的场景,使用ThreadLocal可以在一定程度上减少锁竞争。

二、并发类容器介绍

ConcurrentHashMap:hashtable的替代品。

CopyOnWriteArrayList:Vector的替代品。

ConcurrentLinkedQueue和LinkedBlockingQueue,前者是高性能的队列,后者是以阻塞形式的队列。

Queue的是先类还有很多:如ArrayBlockingQueue、PrirotyBlockingQueue、SynchronousQueue等;

1、ConcurrentMap接口有两个重要的实现类:ConcurrentHashMap和ConcurrentSkipListMap(支持并发排序功能,弥补ConcurrentHashMap不足)。

  ConcurrentHashMap内部使用分段(Segment)锁。每个段其实就是以个小的hashsTable,他们有自己的锁。只要多个修改操作发生在不同的段上,他们就可以并发进行。把一个整体分成了16个段(Segment)。也就是最高支持16个线程的并发修改操作。这也是在多线程场景时减小锁的粒度从而降低锁竞争的一种方案。并且代码中大多共享变量使用Volatile关键字生命,目的是第一时间获取修改的内容,性能非常好。

2、CopyOnWrite:CopyOnWriteArrayList和CopyOnWriteArraySet。

  CopyOnWrite是写时复制的容器,通俗的理解是当我们往一个容器中添加元素的时候,不直接往当前容器中添加,而是先将当前容器进行Copy,复制出一个新的容器,然后新的容器里添加元素,元素添加完后,再将原容器的引用指向新的容器。这样做的好处是我们可以对CopyWrite容器进行并读,而不需要枷锁,因为当前容器不会添加任何元素,所以CopyOnWrite容器也是一种读写分离的思想,读和写不同的容器。

3、并发Queue:一个是以ConcurrentLinkedQueue为代表的高性能和LinkedBlockingQueue接口为代表的阻塞队列。都是继承自Queue。

ConcurrentLinkedQueue是一个适用于高并发场景下的队列,通过无锁的方式,实现了高并发状态下的高性能,通常ConcurrentLinkedQueue性能好于BlockingQueue,它是基于链接点的无界线程安全队列。该队列的元素遵循先进先出的原则。且不允许null元素。

ConcurrentLinkedQueue的重要方法:

  add()和offer()都是加入元素的方法:在ConcurrentLinkedQueue中,俩方法无任何区别。

  poll()和peek()都是取头元素的节点,区别在于前者会删除元素,后者不会。

BlockingQueue接口:

ArrayBlockingQueue:基于数组的队列实现,在ArrayBlockingQueue内部,维护了一个定长数组,以便缓存队列中的数据对象,其内部没有实现读写分离,也就意味着生产者和消费者不能完全并行,长度是需要定义的,可以制定先进先出或者先进后出,也叫有界队列。

LinkedBlockingQueue:基于链表的阻塞队列,同ArrayBlockingQueue类似,其内部也维持着一个数据缓冲队列(该队列由一个链表构成),LinkedBlockingQueue之所以能够高效的处理并发数据,是因为其内部实现采用分离锁(读,写分离两个锁),从而实现生产者和消费者完全并行运行,它是一个无界队列。

SynchronousQueue:一种没有缓冲的队列,生产者产生的数据直接会被消费者获取并消费。

ProrityBlockingQueue:基于优先级的阻塞队列(优先级的判断通过构造函数传入的Compator对象来决定,也就是说传入队列的对象必须实现Comparable接口),在实现ProrityBlockingQueue时,内部控制线程同步的锁采用的是公平锁,他也是一个无界队列。

DelayQueue:带有延迟时间的Queue,其中的元素只有当其指定的延迟时间到了,才能够从队列中获取到该元素。DelayQueue中的元素必须实现Delay接口,DelayQueue是一个没有大小限制的队列,应用场景很多,比如对缓冲超市的数据进行移除,任务超时处理、空闲链接的关闭等等。

原文地址:https://www.cnblogs.com/dwxblogs/p/10909272.html

时间: 2024-10-05 23:27:06

java多线程(二)的相关文章

java多线程(二)——用到的设计模式

接上篇:java多线程(一)http://www.cnblogs.com/ChaosJu/p/4528895.html java实现多线程的方式二,实现Runable接口用到设计模式——静态代理模式 一.代理模式 代理模式的定义 代理模式(Proxy Pattern)是对象的结构型模式,代理模式给某一个对象提供了一个代理对象,并由代理对象控制对原对象的引用. 代理模式不会改变原来的接口和行为,只是转由代理干某件事,代理可以控制原来的目标,例如:代理商,代理商只会卖东西,但并不会改变行为,不会制造

从零开始学习Java多线程(二)

前面已经简单介绍进程和线程,为后续学习做铺垫.本文讨论多线程传参,Java多线程异常处理机制. 1. 多线程的参数传递 在传统开发过程中,我们习惯在调用函数时,将所需的参数传入其中,通过函数内部逻辑处理返回结果,大多情况下,整个过程均是由一条线程执行,排除运行不必要的的偶发性,似乎并不会出现意料之外的结果.而在多线程环境下,在使用线程时需要对线程进行一些必要的初始化,线程对这些数据进行处理后返回结果,由于线程的运行和结束并不可控,线程传参变得复杂起来,本文就以上问题介绍三种常用的传递参数方式.

Java多线程(二) 多线程的锁机制

当两条线程同时访问一个类的时候,可能会带来一些问题.并发线程重入可能会带来内存泄漏.程序不可控等等.不管是线程间的通讯还是线程共享数据都需要使用Java的锁机制控制并发代码产生的问题.本篇总结主要著名Java的锁机制,阐述多线程下如何使用锁机制进行并发线程沟通. 1.并发下的程序异常 先看下下面两个代码,查看异常内容. 异常1:单例模式 1 package com.scl.thread; 2 3 public class SingletonException 4 { 5 public stati

java多线程二之线程同步的三种方法

java多线程的难点是在:处理多个线程同步与并发运行时线程间的通信问题.java在处理线程同步时,常用方法有: 1.synchronized关键字. 2.Lock显示加锁. 3.信号量Semaphore. 线程同步问题引入: 创建一个银行账户Account类,在创建并启动100个线程往同一个Account类实例里面添加一块钱.在没有使用上面三种方法的情况下: 代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25

Java多线程——<二>将任务交给线程,线程声明及启动

一.任务和线程 <thinking in java>中专门有一小节中对线程和任务两个概念进行了具体的区分,这也恰好说明任务和线程是有区别的. 正如前文所提到的,任务只是一段代码,一段要达成你目的的代码,这段代码写在哪,怎么写其实无所谓,只是因为你希望java的多线程机制能够识别并调用你编写的任务,所以规定了Runnable接口,让你的任务来实现该接口,把你想做的工作在实现该接口的run方法中实现. 那么,已经定义了任务类,那任务和线程有什么关系呢? java的线程是用来驱动任务执行的,也就是说

java多线程(二)——锁机制synchronized(同步方法)

synchronized Java语言的关键字,可用来给对象和方法或者代码块加锁,当它锁定一个方法或者一个代码块的时候,同一时刻最多只有一个线程执行这段代码.当两个并发线程访问同一个对象object中的这个加锁同步代码块时,一个时间内只能有一个线程得到执行.另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块.然而,当一个线程访问object的一个加锁代码块时,另一个线程仍然可以访问该object中的非加锁代码块. ——以上来源百度百科 一.方法内的变量为线程安全 “非线程安全”的问题

Java 多线程(二)之 Thread 优先级

Thread 中线程优先级相关属性 每个线程均有优先级,在 Thread 中, 与优先级对应的属性如下: /** * 线程的优先级属性 */ private int priority; /** * 线程所能拥有的最大优先级. */ public final static int MIN_PRIORITY = 1; /** * 线程默认的优先级. */ public final static int NORM_PRIORITY = 5; /** * 线程所能拥有的最大优先级. */ public

Java多线程 二 线程间通信

线程间通信: 多个线程在处理同一资源,但是 等待唤醒机制 涉及的方法: 1.wait() 让线程处于冻结状态,被wait的线程会被存储到线程池中. 2.notify() 唤醒线程池中的一个线程(任意) 3.notifyAll() 唤醒线程池中的所有线程.. 这些方法都必须定义在同步中, 因为这些方法是用于操作线程状态的方法. 必须明确到底操作的那个锁上的线程. 为什么操作线程的方法wait notify notifyAll定义在了Object中. 因为这些方法是监视器方法,监视器其实就是锁. 锁

Java多线程(五) Lock接口,ReentranctLock,ReentrantReadWriteLock

在JDK5里面,提供了一个Lock接口.该接口通过底层框架的形式为设计更面向对象.可更加细粒度控制线程代码.更灵活控制线程通信提供了基础.实现Lock接口且使用得比较多的是可重入锁(ReentrantLock)以及读写锁(ReentrantReadWriteLock). 1. ReentrantLock 在Java多线程(二) 多线程的锁机制 里面,已经总结过通过使用Synchronized关键字实现线程内的方法锁定.但使用Synchronized关键字有一些局限性,上锁和释放锁是由JVM决定的