美文网首页
java多线程笔记

java多线程笔记

作者: 我是电饭煲 | 来源:发表于2020-03-30 19:43 被阅读0次

产生死锁的四个必要条件

(1) 互斥条件:一个资源每次只能被一个进程使用。
(2) 占有且等待:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
(3)不可强行占有:进程已获得的资源,在末使用完之前,不能强行剥夺。
(4) 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。

处理死锁的基本方法

  • 死锁预防
通过设置某些限制条件,去破坏死锁的四个条件中的一个或几个条件,来预防发生死锁。但由于所施加的限制条件往往太严格,因而导致系统资源利用率和系统吞吐量降低。
  • 死锁避免
允许前三个必要条件,但通过明智的选择,确保永远不会到达死锁点,因此死锁避免比死锁预防允许更多的并发。
  • 死锁检测
不须实现采取任何限制性措施,而是允许系统在运行过程发生死锁,但可通过系统设置的检测机构及时检测出死锁的发生,并精确地确定于死锁相关的进程和资源,然后采取适当的措施,从系统中将已发生的死锁清除掉。
  • 死锁解除
与死锁检测相配套的一种措施。当检测到系统中已发生死锁,需将进程从死锁状态中解脱出来。常用方法:撤销或挂起一些进程,以便回收一些资源,再将这些资源分配给已处于阻塞状态的进程。死锁检测盒解除有可能使系统获得较好的资源利用率和吞吐量,但在实现上难度也最大。

https://blog.csdn.net/rabbit_in_android/article/details/50530960

java 锁

  • ReentrantLock
可重入锁
互斥锁
默认非公平锁,可设置公平锁

http://www.matools.com/api/java8
https://www.jianshu.com/p/c5cde8dfa6de

java锁思维导图

https://mm.edrawsoft.cn/template/5086

锁思维导图

image.png

常见锁的区别及适用场景

https://blog.csdn.net/u012658346/article/details/51188116

互斥锁、自旋锁优缺点和使用场景

https://blog.csdn.net/u010035604/article/details/84344576

悲观锁和乐观锁的使用场景与实现

  • 乐观锁
使用版本号机制或CAS算法
代码实现(CAS算法):AtomicInteger
使用场景:多读。不在乎有脏读情况出现。适合针对一个变量,不适合代码块。
优点:能保证原子性。
缺点:脏读。ABA问题。
ABA问题解决办法:除了旧值比较外,还要比较时间戳。
  • 悲观锁
使用场景:比较适合强一致性的场景。多写。
缺点:效率比较低,特别是读的并发低。

https://juejin.im/post/5b4977ae5188251b146b2fc8

ReentrantReadWriteLock读写锁

  • 使用场景:对共享资源有读和写的操作,且写操作没有读操作那么频繁。在没有写操作的时候,多个线程同时读一个资源没有任何问题,所以应该允许多个线程同时读取共享资源;但是如果一个线程想去写这些共享资源,就不应该允许其他线程对该资源进行读和写的操作了。

volatile作用

https://www.cnblogs.com/zhengbin/p/5654805.html

java holdsLock()方法检测一个线程是否拥有锁

https://www.cnblogs.com/dolphin0520/p/3958019.html

线程池思维导图

https://blog.csdn.net/WuLex/article/details/103679550

常见java多线程面试题集合(用于过一遍,查漏补缺)

https://www.cnblogs.com/dolphin0520/p/3958019.html

线程平滑退出方法

两种实现线程的方式

  • extends Thread
class PrimeThread extendsThread {
  long minPrime;
  PrimeThread(long minPrime) {
    this.minPrime = minPrime;
}

public void run() {
  
}
}

// 启动方式
PrimeThread p = new PrimeThread(123);
p.start();
  • extends Runnable
class PrimeRun extendsThread {
  long minPrime;
  PrimeThread(long minPrime) {
    this.minPrime = minPrime;
}

public void run() {
  
}
}

// 启动方式
PrimeRun p = new PrimeRun (123);
new Thread(p).start();

为了防止一个线程占用cpu过久,使用yield进行礼让

ThreadPoolExecutor

ConcurrentHashMap使用场景

  • 在并发场景下,使并发效率更高
  • 在并发场景下,线程安全
  • 并发执行时,线程安全的容器只能保证自身的数据不被破坏,但无法保证业务的行为是否正确

java各种并发容器讲解(马士兵)

https://www.bilibili.com/video/av33688545/?p=6

生产者消费者问题,解决方案

  • wait、notify
  • ReentrantLock、condition

ReentrantLock可从入锁

  • 用于代替synchronized
  • 这是手工锁,需要手动释放
  • .lock()写在try外面
  • 公平锁

synchronized

  • 一个同步方法可以调用另一个同步方法。
  • 一个线程已经拥有某个对象的锁,再次申请的时候仍然会得到该对象的锁。
  • 是重入锁。
  • 程序在执行过程中,如果出现异常,默认情况锁会被释放,不然可能会发送不一致的情况。
  • 不要以字符串变量作为锁对象。
  • wait、notify

wait释放锁,notify不释放锁
wait和while 99%的情况都是用在一起

门闩:countDownLatch(并发性好)

volatile关键字

  • 使一个变量在多线程间可见
  • 会让所有线程都会督导变量的修改值
  • 作用:一个线程修改了被volatile声明的变量,会告诉其他线程,这个值被修改了,请你到内存你再重新读取
  • 使用场景

在变量运算不依赖当前值
变量不需要与其他状态变量共同参与不变约束
最佳实践就是使用volatile修饰的标志位来控制线程的停止

解决多线程安全问题的几种同步方法

  • 同步代码块
  • 同步方法
  • 锁机制

相关文章

网友评论

      本文标题:java多线程笔记

      本文链接:https://www.haomeiwen.com/subject/qxoedctx.html