一、公平锁与非公平锁

  公平锁:加锁前检查是否有排队等待的线程,优先排队等待的线程,先来先得

  非公平锁:加锁时不考虑排队等待问题,直接尝试获取锁,获取不到自动到队尾等待

  非公平锁性能比公平锁高5~10倍,因为公平锁需要在多核的情况下维护一个队列。Java中的ReentrantLock 默认的lock()方法采用的是非公平锁。通过调用有参构造设置是否为公平与非公平锁

   

二、可重入锁(递归锁)

  1.广义上的可重入锁指的是可重复可递归调用的锁,在外层使用锁之后,在内层仍然可以使用,并且不发生死锁(前提得是同一个对象或者class),这样的锁就叫做可重入锁。ReentrantLock和synchronized都是可重入锁

  2.特点:获取到外面的锁,就能拿到里面的锁(自动获取;就像自己家一样,拿钥匙开门之后,进卧室不用开锁)

   3.代码:

public class MyDemo {
public static void main(String[] args) {
testLock();
} public static void testSynchronized() {
Phone phone = new Phone();
new Thread(() -> {
phone.sms();
}, "A").start();
new Thread(() -> {
phone.sms();
}, "B").start();
} public static void testLock() {
Phone2 phone = new Phone2();
new Thread(() -> {
phone.sms();
}, "A").start();
new Thread(() -> {
phone.sms();
}, "B").start();
}
} class Phone {
public synchronized void sms() {
System.out.println(Thread.currentThread().getName() + "sms");
call(); // 这里也有锁
} public synchronized void call() {
System.out.println(Thread.currentThread().getName() + "call");
}
} class Phone2 {
Lock lock = new ReentrantLock(); public void sms() {
lock.lock(); // 细节问题:lock.lock(); lock.unlock(); // lock 锁必须配对,否则就会死在里面
lock.lock();
try {
System.out.println(Thread.currentThread().getName() + "sms");
call(); // 这里也有锁
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
lock.unlock();
}
} public void call() {
lock.lock();
try {
System.out.println(Thread.currentThread().getName() + "call");
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}

三、自旋锁

  1.是指当一个线程在获取锁的时候,如果锁已经被其它线程获取,那么该线程将循环等待,然后不断的判断锁是否能够被成功获取,直到获取到锁才会退出循环。获取锁的线程一直处于活跃状态,但是并没有执行任何有效的任务,使用这种锁会造成busy-waiting。

  2.在CAS中,Unsafe类里面的方法getAndAddInt()里面就是实现的自旋锁

  代码:

public class MyDemo {

    AtomicReference<Thread> atomicReference = new AtomicReference<>();

    // 加锁
public void myLock() {
Thread thread = Thread.currentThread();
System.out.println(Thread.currentThread().getName() + "==> mylock");
// 自旋锁
while (!atomicReference.compareAndSet(null, thread)) { }
} // 解锁
public void myUnLock() {
Thread thread = Thread.currentThread();
System.out.println(Thread.currentThread().getName() + "==> myUnlock");
atomicReference.compareAndSet(thread, null);
} public static void main(String[] args) throws InterruptedException {
MyDemo lock = new MyDemo(); new Thread(() -> {
lock.myLock();
try {
TimeUnit.SECONDS.sleep(5);
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.myUnLock();
}
}, "T1").start(); TimeUnit.SECONDS.sleep(1); new Thread(() -> {
lock.myLock();
try {
TimeUnit.SECONDS.sleep(1);
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.myUnLock();
}
}, "T2").start();
}
}

四、死锁

  1.死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去

  2.死锁产生的必要条件

    互斥条件、请求和保持条件、不剥夺条件、环路等待条件

  3.死锁产生的原因:

    竞争不可抢占性资源(或竞争可消耗资源)、进程推进顺序不当

  4.避免与解决死锁的算法:死锁预防(有序资源分配法、银行家算法)   解决死锁(死锁预防、死锁避免、死锁检测和解除)

  5.java中发生死锁的查看方式

    1.运行发生死锁的代码

    2.在程序运行时,使用  jps -l查看当前进程号

    3.使用jstack 进程号找到死锁问题

最新文章

  1. Oracle数据库优化的经验总结
  2. JavaScript数据类型 typeof, null, 和 undefined
  3. HTML table、form表单标签的介绍
  4. sqlldr
  5. swift 动手写网络请求封装(仿照了一个大神的)不用导入第三方
  6. Html Mailto标签详细使用方法
  7. LintCode Binary Tree Level Order Traversal
  8. [Shell]正则表达式与通配符
  9. 高手指南PHP安装配置
  10. 转:HTTP 301 跳转和302跳转的区别
  11. 怎么书写高质量jQuery代码
  12. Rsyslog配置
  13. strcmp的源码实现
  14. mysql 查询大量数据内存溢出
  15. js给div动态添加控件,然后给这个控件动态添加事件
  16. 201521123003《Java程序设计》第13周学习总结
  17. distcc (dcc_execvp) ERROR: failed to exec XX: Permission denied
  18. Android应用---基于NDK的samples例程hello-jni学习NDK开发
  19. CentOS7 安装FastDFS分布式文件系统
  20. css3硬件加速

热门文章

  1. 阿里云恶意软件检测比赛-第三周-TextCNN
  2. Linux系统编程—条件变量
  3. 读完这篇,让你真正理解Redis持久化
  4. _1_html_框架
  5. # 初体验之腾讯位置服务彩云天气开发者api
  6. Spring Cloud系列(二):Eureka应用详解
  7. 工作流引擎Activiti与SpringBoot2整合--开源软件诞生17
  8. Excel双击“单元格”后,自动跳转到相关“工作表
  9. 053 01 Android 零基础入门 01 Java基础语法 05 Java流程控制之循环结构 15 流程控制知识总结
  10. DORIS系统概述