• 自旋锁,死锁与重入锁


    重入锁

    重入锁---- 能够让线程进行重入的锁叫作重入锁
    锁重入----让线程进行重入的过程叫作锁的重入

    public class demo {
    public static synchronized void a() {  
    System.out.println("a");
    b();
    }
    private static synchronized void b() {
    System.out.println("b");
    }
    public static void main(String[] args) {
    new Thread(new Runnable() {
    @Override
    public void run() {
    demo.a();
    }
    }).start();;
    }
    }

    锁是当前类的实例,当进入a方法的时候,线程必须先拿到当前类的实例(锁),这个时候,a的方法内同时调用了b方法,b方法也是用synchronized来修饰的,所以b方法也需要线程获取锁才能让线程进来

     进入a方法的时候,线程拿的锁是当前类的实例(锁),当线程要进入b方法的时候,线程拿的锁也是当前类的实例(锁),前一把锁和后一把锁都是同一个把锁,这个时候就发送了锁重入现象

     1 public class Demo {
     2     
     3     
     4     /*
     5      * synchronized锁在方法上锁的对象是当前类的实例
     6      */
     7     public synchronized void a() {
     8         System.out.println("a");
     9 //        b();
    10         
    11         
    12         try {
    13             Thread.sleep(1000);
    14         } catch (InterruptedException e) {
    15             // TODO Auto-generated catch block
    16             e.printStackTrace();
    17         }    
    18     }
    19     
    20     
    21     public synchronized void b() {
    22         System.out.println("b");
    23         
    24         try {
    25             Thread.sleep(1000);
    26         } catch (InterruptedException e) {
    27             // TODO Auto-generated catch block
    28             e.printStackTrace();
    29         }
    30         
    31     }
    32     
    33     
    34     public static void main(String[] args) {
    35         Demo d = new Demo();
    36         
    37         new Thread(new Runnable() {
    38 
    39             @Override
    40             public void run() {
    41                 d.a();
    42             }
    43         }).start();
    44         
    45         
    46         new Thread(new Runnable() {
    47 
    48             @Override
    49             public void run() {
    50                 d.b();
    51             }
    52         }).start();
    53     }
    54 
    55 } //当调用a时没有调用b

    自旋锁

    “旋”的是CPU的时间片,空转CPU,当一个 线程拿到对象头的信息到栈帧中,另外的线程再想获取必须不停自旋等待第一个线程方法体执行完毕之后才能自己再去执行。

     1 public class Demo2 {
     2     
     3     public static void main(String[] args) {
     4         new Thread(new Runnable() {
     5             @Override
     6             public void run() {
     7                     System.out.println(Thread.currentThread().getName() + "线程开始执行..."); 
     8                     try {
     9                         Thread.sleep(new Random().nextInt(2000));
    10                     } catch (InterruptedException e) {
    11                         // TODO Auto-generated catch block
    12                         e.printStackTrace();
    13                     }
    14                     System.out.println(Thread.currentThread().getName() + "线程执行完毕了...");
    15             }
    16             
    17         }).start();
    18     
    19         //第二个线程
    20         
    21         new Thread(new Runnable() {
    22             @Override
    23             public void run() {
    24                     System.out.println(Thread.currentThread().getName() + "线程开始执行..."); 
    25                     try {
    26                         Thread.sleep(new Random().nextInt(2000));
    27                     } catch (InterruptedException e) {
    28                         // TODO Auto-generated catch block
    29                         e.printStackTrace();
    30                     }
    31                     System.out.println(Thread.currentThread().getName() + "线程执行完毕了...");
    32             }
    33             
    34         }).start();
    35         
    36         //第三个线程
    37         
    38         new Thread(new Runnable() {
    39             @Override
    40             public void run() {
    41                     System.out.println(Thread.currentThread().getName() + "线程开始执行..."); 
    42                     try {
    43                         Thread.sleep(new Random().nextInt(2000));
    44                     } catch (InterruptedException e) {
    45                         // TODO Auto-generated catch block
    46                         e.printStackTrace();
    47                     }
    48                     System.out.println(Thread.currentThread().getName() + "线程执行完毕了...");
    49             }
    50             
    51         }).start();
    52         
    53         while(Thread.activeCount() !=1) {
    54             //自旋
    55         }
    56         
    57         
    58         System.out.println("所有的线程执行完毕了...");
    59         
    60     }
    61 
    62 }

    死锁

    public class Demo3 {
        
        private Object obj1 = new Object();
        private Object obj2 = new Object();
        
        public void a() {
            synchronized (obj1) {
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                synchronized (obj2) {
                    System.out.println("a");
                }
                
            }
        }
        
        public void b() {
            synchronized (obj2) {
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                synchronized (obj1) {
                    System.out.println("b");
                }
            }
        }
        
        public static void main(String[] args) {
            Demo3 d = new Demo3();
            
            new Thread(new Runnable() {
    
                @Override
                public void run() {
                    d.a();
                    
                }
                
            }).start();
            
            new Thread(new Runnable() {
    
                @Override
                public void run() {
                    d.b();
                    
                }
                
            }).start();
            
        }
    
    }

    可以使用jdk自带的jconsole来检查死锁

  • 相关阅读:
    BugKu web 矛盾
    BugKu 域名解析
    Dummy game
    BugKu 变量1
    BugKu web5
    递归算法
    Django进阶(转载)
    centos 7防火情配置
    cenos7切换阿里源
    centos7 编译安装nginx
  • 原文地址:https://www.cnblogs.com/quyangyang/p/10367153.html
Copyright © 2020-2023  润新知