有关线程并发的学习(一)

来源:互联网 发布:淘宝代购only是正品吗 编辑:程序博客网 时间:2024/05/20 18:40

一、线程安全:

1.概念:当多个线程访问一个类(对象或方法)是,这个类始终都能表现出正确的行为,那么这个类(对象或方法)就是线程安全

2.synchronized:可以在任意对象及方法上加锁,而加锁的这段代码称之为“互斥区”或“临界区”。

总结:当多个线程访问一个run方法的时候,以排队的方式进行处理(这里的排队是按照CPU分配的先后顺序),一个线程想要执行synchronized修饰的方法里的代码,首先尝试获得锁,如果拿到锁,执行synchronized代码具体内容,拿不到锁,这个线程就会不断的尝试获得这把锁,直到拿到为止,而且是多个线程同时去竞争这把锁(也就会有锁竞争的问题)。

3.多个线程多个锁:多个线程,每个线程都可以拿到自己指定的锁,分别获得锁之后,执行synchronized方法体的内容。

总结:关键字synchronized取得的锁都是对象锁,而不是把一段代码(方法)当作锁,所以哪个线程先执行synchronized关键字方法,哪个线程就持有该方法所属对象的锁(Lock),两个对象,线程就是获得两个不同的锁,他们互不影响。

      有一种特殊情况则是相同的,就是在静态方法上加上synchronized关键字,则表示锁定.class类,是类级别的锁(独占.class)类。

4.对象锁的同步和异步

同步:synchronized,同步的概念就是共享,如果不是共享的资源,就没有必要进行同步

异步:asynchronized, 异步的概念就是独立,相互之间不受到任何制约

5.脏读

我们对一个对象的方法加锁的时候,要保证业务的原子性,不然会出现业务错误。

6.volatile关键字

主要作用是使变量在多个线程间可见。

注意:volatile关键字虽然拥有多个线程之间的可见性,但是却不具备同步性(也就是原子性),可以算是一个轻量级的synchronized,性能要比asynchronized强很多,不会造成阻塞,一般volatile用于只针对与多个线程可见的变量操作,不能代替synchronized的同步功能。

volatile关键字只具有可见性,没有原子性,要实现原子性建议使用atomic类的系列对象支持原子操作(注意atomic类只保证本身方法的原子性,并不保证多次操作的原子性)

7.线程之间的通信

线程是操作系统中独立的个体,但这些个体如果不经过特殊的处理就不能成为一个整体,线程间的通信就成为整体的比用方式之一,当线程存在通信指挥,系统间的交互性会更强大,在挺高CPU利用率的同时还会使开发人员对线程任务在处理的过程中进行有效的把控与监督。

使用wait/notify方法实现线程间的通信,必须配合synchronized关键字使用。

wait方法释放锁,notify方法不释放锁。

如果想实现实时效果,可以使用java.util.current.CountDownLatch类的await/countDown去实现。

8.ThreaLocal

是为现成的局部变量,是一种多线程间并发访问变量的解决方案。与其synchronized等加锁方式不同,ThreadLocal完全不提供锁,而使用以空间换时间的手段,为每个线程提供变量的独立副本,以保障线程安全。

9.并发类容器

ConcurrentMap:它有两个重要的实现 ConcurrentHashMap和ConcurrentSkipListMap(支持并发排序,弥补ConcurrentHashMap)

Copy-On-Write容器:简称COW,是一种基于设计中的优化策略。

JDK中的COW容器有两种,CopyOnWriteArrayList和CopyOnWriteArraySet,COW容器非常有用,可以在非常多的并发场景中使用。

10.并发Queue

在并发队列上JDK提供了两套实现,一个是以ConCurrentLinkedQueue为代表的高性能队列,一个是以BlockingQueue接口为代表的阻塞队列,无论哪种,都继承Queue

ConCurrentLinkedQueue:适用于高并发场景下的队列,通过无锁的方式,实现了高并发状态下的高性能。不允许null元素。头是最新加入的,尾是最近加入的,遵循先进先出的原则。

重要方法:add()和offer()都是加入元素(在ConCurrentLinkedQueue中,没有区别)

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

BlockingQueue接口:

ArrayBlockingQueue:基于数组的阻塞队列实现,内部没有实现读写分离,生产和消费不能完全并行,长度是需要定义的,可以指定先进先出或者是先进后出,也叫有界队列。

LinkedBlockingQueue:基于链表的阻塞队列,之所以能够高效的处理并发数据,因为内部采用分离锁(读写分离两个锁),实现生产和消费操作的完全并行运行,是无界队列。

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

PriorityBlockingQueue:基于优先级的阻塞队列(优先级的判断通过构造函数传入的Compare对象来决定,也就是说出入对象必须实现Comparable接口),他也是一个无界队列。‘’

DelayQueue:带有延迟时间的Queue,其中的元素只有当指定的延时时间到了,才能够从队列中获取到该元素。DelayQueue中的元素必须实现Delayed接口。

11.Future模式

Future模式类似于商品订单。或者说更形象的是我们发送Ajax请求。











0 0
原创粉丝点击