1.线程不安全的类 -->线程安全的类
1.1StringBuilder--->StringBuffer
1.2 SimpleDateFormate --->joda.timez中的DateTime
1.3 ArrayList . HashSet HashMap 等Collections (对应转化的线程安全的类比较多)
比如:
(线程安全---同步容器)
ArrayList 对应的线程安全的类有:vector stack
HashMap 对应的有HashTable (但是其中的key 和value不能同时为null)
Collections .synchronizedxxx (List,Set,Map)
2.线程安全---并发容器之J.U.C
2.1 ArrayList -->CopyOnWriteArrayList 写操作复制
缺点: 1. 写操作需要复制数组
2.元素比较多的情况下,容易引起youngGC或fullGC
3.不能实时读,只能满足最终一致性。
读不加锁,但是写加锁
2.2 HashSet . -->CopyOnWriteArraySet
TreeSet --> ConcurrentSkipListSet : 其中的批量操作 addAll 等不能满足原子性
2.3 HashMap -->ConcurrentHashMap
TreeMap --> ConcurrentSkipListMap: 1.key 有序 2.支持更高的并发
安全共享对象的策略--总结
1.线程限制:一个被线程限制的对象,由线程独占,并且只能被占有他的线程修改
2.共享只读:一个共享只读的对象,在没有额外同步的情况下,可以被多个线程并发访问,且任何线程不能修改
3.线程安全对象:一个线程安全的对象或者容器,在内部通过同步机制来保证线程安全,所以其他的线程无需额外的同步就可以通过公共接口随意访问它
4.被守护的对象:被守护的对象只能通过特定的锁来访问。
J.U.C的AQS(基于双向链表的队列实现)
1.使用node实现先进先出的队列,可以用于构建锁或者其他同步装置的基础框架
2.利用了一个int类型表示状态
3.使用方法是继承
4.子类通过继承并通过实现它的方法管理其装态;{acquire 和release}的方法操纵装态
5.可以同时实现拍他锁和共享锁模式(独占和共享)
AQS的同步组件
1.CountDownLatch
1.1如果是做递减操作,需要将CountDownLatch的countDown这个方法的操作放到finally里面
1.2 awai(10,TimUnit.MillISECONDS)指定时间等待
2.Semaphore
有限资源,用于并发控制
参数声明的时候,可以通过参数表示 用户控制同一个时间的线程的并发数
例如:
final Sempahore sempahore = new Sempahore(5); //表示允许线程并发的数量就是5
2.1获取一个许可
semaphore.acquire(); //获取一个许可
semaphore.release(); //释放一个许可
2.2获取多个许可
semaphore.acquire(5); //如果获取声明的数量的话,就会造成不存在并发
semaphore.release(5);
2.3尝试获取许可
if(semaphore.tryAcquire())
2.4尝试等待获取许可
if(semaphore.tryAcquire(1,TimUnit.SECONDS)) //1秒内尝试获取许可
3.CycliBarrier:多个线程相互等待的关系,只有线程准备完毕之后才进行下面的操作
CycliBarrier(用A表示)与CountDownLatch(用B表示)的区别
1.A只能使用一次 ;描述一个或多个线程等待其他线程的关系
2.B能够使用多次,可以使用reset方法重复使用;多个线程相互等待,只有所有线程满足条件之后,才能继续执行后续的操作
关键点:
3.1声明
private static CyclicBarrier barrier = new CyclicBarrier(3);
//声明允许等待的并发数
3.2 在每个方法体内,调用 barrier.await();(每一个线程 等待时间)
同时该方法可以设置等待时间
barrier.await(2000,TimUnit.MILLISECONDS)
注:该await方法存在三种异常,注意进行捕获,同时捕获多种异常的方式有
catch(BrokenBarrierException| TimeOutExcetion e){}