多线程高并发总结

1、synchronized对某个对象加锁(互斥锁),申请的纪录在堆内存里的对象,执行完代码就释放。

2、synchronized锁的是对象,而不是代码块。

3、在方法上加synchronized相当于synchronized(this)。

4、synchronized用在静态方法上,相当于synchronized(T.class),即锁住类对象。

5、各个代码块之间没有原子性,执行需要重新争夺CPU执行权。

6、同步方法和非同步方法能同时被访问。

7、对业务写方法加锁,对业务读方法不加锁,容易产生脏读问题。

8、一个同步方法可以调用另外一个同步方法,一个线程已经拥有某个对象的锁,再次申请的时候仍然会得到该对象的锁,也就是说synchronized获得的锁是可重入的。

9、子类的同步方法可以调用父类的同步方法。

10、程序在执行过程中,如果出现异常,默认情况锁会被释放。所以,在并发处理的过程中,有异常要多加小心,不然可能会发生不一致的情况,不想释放就用try...catch...。

11、volatile关键字:使一个变量在多个线程间可见。分析:在jmm中,每一个线程在执行过程中,有自己的一块内存,把主内存的数据copy进来,再修改(CPU空闲时有可能去主内存刷一下),处理完就放回主内存。加了volatile,一旦发生改变,通知其它线程去主内存重新获取。

12、volatile并不能保证多个线程共同修改一个变量时所带来的不一致问题,也就是说volatile(只保证可见性)不能替代synchronized(保证可见性,原子性),能用volatile就不要用synchronized(重量级)。

13、count++不具备原子性,实际分了三步执行。thread.join()方法,阻塞,等待该线程执行完毕。

14、AtomicXXX的单个方法具有原子性,但多个方法连续调用则不保证。

15、synchronized优化:同步代码块中的语句越少越好,不需同步的代码块不要加锁。

16、锁定某对象o,如果o的对象属性发生改变,不影响锁的使用。但是如果o变成了另外一个对象,则锁定的对象发生改变。应该避免将锁定的对象的引用变成另外的对象。

17、不要以字符串常量作为锁对象。

18、CountDownLatch:一个同步辅助类,在完成一组正在其它线程中执行的操作之前,它允许一个或多个线程一直等待。使用:不需要锁定任何对象,await方法等待,countDown方法调用一次计数减少一次,当初始值变为0就释放锁。

19、ReentrantLock实现Lock接口,用于替代synchronized关键字,lock.lock()相当于synchronized(this),必须手动释放锁lock.unlock(),可以用try...finally...,尝试性锁lock.tryLock(),可以指定等待时间,对interrupt方法做出相应lock.lockInterruptibly(),可被打断锁,用lock.interrupt打断,公平锁:synchronized抢占式(不公平),new ReentrantLock(true

)等待时间长的先得到。

20、固定容量同步容器的实现:

(1)wait和notify:wait方法基本结合while(而不是if)使用,永远使用notifyAll方法唤醒。

(2)Lock和Condition:精确指定唤醒哪些线程。

21、ThreadLocal:线程局部变量,相当于每个线程有自己的一份,各自维护,互不影响。空间换时间,注意内存溢出问题。

22、单例模式的实现方法:饿汉模式、懒汉模式(同步方法)、懒汉模式(双重检测锁)、内部类、枚举类。

23、ArrayList不同步,Vector同步(所有方法加锁),一段代码,只要不存在原子性,那么就有可能存在线程安全问题。

24、同步容器存放于包java.util.concurrent中。可以用Collection.synchronizedXXX为普通容器加锁(并发不高时可以使用)。

写时复制CopyOnWriteList:适用于写少读多。

ConcurrentMap:ConcurrentHashMap(大锁分小锁)、ConcurrentSkipListMap(支持高并发和排序)。

Queue:队列,先进先出,通用方法有add,offer,remove,poll,element,peek。具体作用看API文档。

Deque:双向队列,可以从两边读写。

具体实现类如下:

ConcurrentLinkedQueue:并发加锁

BlockingQueue:阻塞式锁,put满了会阻塞

子类LinkedBlockingQueue:无界

子类ArrayBlockingQueue:有界

DelayQueue:执行定时任务,TransferQueue:transfer实时消息处理,SynchronizedQueue:put方法阻塞。

25、Executor:执行器

ExecutorSevice:执行器服务,有execute,submit方法。

Callable:跟Runnable相似,扩展,call方法有返回值,能抛异常。

Executors:操作Executor的工具类,可用于创建多种线程池。

ThreadPool:线程池,能重用就重用,效率高,维护者两个队列:正在执行的、等待执行的。

Future:表示异步计算的结果。

FutureTask:get方法可以拿到线程执行结束返回的结果(可用于并行计算)。

Executors提供的线程池:

CachedThreadPool:可缓存,可重用,可新建。

FixedThreadPool:定长,等待,需要时可新建。

ScheduledThreadPool:定长,定时和周期执行。

SingleThreadExecutor:单线程,任务执行按顺序。

SingleScheduledExecutor:单线程定时。

WorkStealingPool:工作窃取。

26、Java7提供了ForkJoin:ForkJoinTask,两个子类,RecursiveTask有返回值,RecursiveAction无返回值。

Java8的Stream API实现了并行流。

 

备注:本文总结了马士兵老师斗鱼直播课程《多线程高并发》。

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值