zoukankan      html  css  js  c++  java
  • JUC:公平锁、非公平锁、共享锁、独占锁、可重入锁、自旋锁、死锁、死锁排查方法


    各种锁的理解


    1、公平锁、非公平锁

    公平锁:非常公平,任何线程获得公平锁,那么就会执行锁中业务直到结束,过程中任何进程都不得干预打扰。不能插队。

    非公平锁:在获得非公平锁之后,执行代码过程中,其他线程可以插入执行,该线程暂停执行,等待其他线程执行完毕,才可继续执行。可插队。(默认非公平锁)


    2、共享锁、独占锁

    共享锁:就是读取锁里的读锁,进行读操作,任何经常都可获得该锁。

    独占锁:就是读取锁里的写锁,只允许一个线程获得该锁。


    3、可重入锁

    可重入锁(递归锁):拿到了外面的锁,内部的锁也都统统拿到了。

    lock锁与synchronized锁都是可重入锁,但是有一定的区别。

    lock锁必须配对,有上锁对应必须就有解锁,不然会死锁。


    4、自旋锁

    在这里插入图片描述

    上图,CAS的源码分析就是一个自旋锁。自旋锁一定是使用CAS做为底层。因为CAS是C++写的原语操作。


    自定义简单的锁

    public class MyLock {
        private AtomicReference<Thread> atomicReference = new AtomicReference<>();
    
        public void lock(){
            // 获取当前执行的线程
            Thread thread = Thread.currentThread();
            System.out.println(thread.getName()+ " => 正在获取自旋锁");
            // CAS操作,自旋锁
            while (!atomicReference.compareAndSet(null,thread)){
    
            }
        }
    
        public void unLock(){
            Thread thread = Thread.currentThread();
            // 解锁,将thread赋值为null,上面的自旋锁就可以解除
            atomicReference.compareAndSet(thread,null);
        }
    }
    
    class MyLockTest{
        public static void main(String[] args) {
            MyLock myLock = new MyLock();
            
            new Thread(()->{
                myLock.lock();
                try{
                    System.out.println("A线程正在执行...");
                    TimeUnit.SECONDS.sleep(5);
                }catch (Exception e){
                    e.printStackTrace();
                }finally {
                    System.out.println("A线程执行完毕!");
                    myLock.unLock();
                }
            },"A").start();
    
            new Thread(()->{
                myLock.lock();
                try{
                    System.out.println("B线程正在执行...");
                }catch (Exception e){
                    e.printStackTrace();
                }finally {
                    System.out.println("B线程执行完毕!");
                    myLock.unLock();
                }
            },"B").start();
        }
    }
    

    输出:

    A => 正在获取自旋锁
    A线程正在执行...(等5秒)
    B => 正在获取自旋锁
    A线程执行完毕!
    B线程正在执行...
    B线程执行完毕!
    

    5、死锁

    就是两个线程都持有各自的锁,但是又要获取对方的锁,此时对方的锁都没有释放,那么就会进入死锁状态。

    public class DieLock implements Runnable{
        private String lock1;
        private String lock2;
    
        public DieLock(String lockA, String lockB) {
            this.lock1 = lockA;
            this.lock2 = lockB;
        }
    
        @Override
        public void run() {
            synchronized (lock1){
                System.out.println(Thread.currentThread().getName() + "要获取" + lock2);
                try {
                    TimeUnit.SECONDS.sleep(4);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
    
                synchronized (lock2){
                    System.out.println(Thread.currentThread().getName() + "要获取" + lock1);
                }
            }
        }
    }
    
    class DieTest{
        public static void main(String[] args) {
            String lockA = "LockA";
            String lockB = "LockB";
    
            // 注意锁的对象
            new Thread(new DieLock(lockA,lockB),"1 ").start();
            new Thread(new DieLock(lockB,lockA),"2 ").start();
        }
    }
    

    输出:

    1 要获取LockB
    2 要获取LockA
    (程序进入无限死锁状态...)
    

    死锁排查 jps

    除了看日志,还可以看堆栈信息

    • 可在Terminal下输入jps -l (java process)定位正在进行的进程号:

    在这里插入图片描述

    • 查询到编号为13860的进程,是DieTest类的。可通过jstack 13860(java stack)查看具体信息:

    在这里插入图片描述

    可查到详细信息,两个进程互相等待对方的锁。


    关于进程、线程、并发、并行的问题

    1. Java中默认有几个线程?

      默认2个线程,一个main线程,一个GC线程

    2. Java真的能开启线程吗?

      不能。

      通过源码private native void start0();分析,java只能通过本地方法去调用开启线程。由底层c语言区操作的。

    3. 并发与并行的区别?

      并发是多个线程同一时间段共同执行一个资源;

      并行是多个线程同一时刻同行。

  • 相关阅读:
    .Net需要掌握的知识
    图片轮播
    vector
    2016ACM青岛区域赛题解
    总是有一个程序的bug没找到
    poj1001_Exponentiation_java高精度
    poj2236_并查集_Wireless Network
    poj1703_Find them, Catch them_并查集
    poj2492_A Bug's Life_并查集
    poj1182食物链_并查集_挑战程序设计竞赛例题
  • 原文地址:https://www.cnblogs.com/turbo30/p/13688199.html
Copyright © 2011-2022 走看看