• Synchronized锁 IT


    可重入锁

      可重入锁指的是在一个线程中可以多次获取同一把锁,比如:一个线程在执行一个带锁的方法,该方法中又调用了另一个需要相同锁的方法,则该线程可以直接获取锁执行调用的方法,而无需重新获得锁。重入则避免了死锁情况的发生。

      例如:当线程1访问testA时,线程2不能访问testB方法,但是可以访问testC;同样,线程2访问testB时,线程1不能访问testA,但是仍然可以访问testC。

      此时,若线程1调用了testA方法,testA方法内调用了testC方法,其他线程同时访问testC方法,若testC方法修改了类成员变量(Java方法里面的局部变量是不存在并发问题的。每个线程都有自己独立的调用栈,局部变量保存在各自的调用栈中,不会被共享,自然也就没有并发问题),就会造成线程安全问题。

    测试类:

     1 public class TestLock {
     2 
     3     synchronized void testA() throws Exception {
     4         System.out.println(Thread.currentThread().getName() + ":this is testA");
     5         Thread.sleep(2000);
     6         testB();
     7         System.out.println(Thread.currentThread().getName() + ":testA is over");
     8     }
     9 
    10     synchronized void testB() throws Exception {
    11         System.out.println(Thread.currentThread().getName() + ":this is testB");
    12         Thread.sleep(2000);
    13         System.out.println(Thread.currentThread().getName() + ":testB is over");
    14     }
    15 
    16     public void testC() {
    17         System.out.println(Thread.currentThread().getName() + ":this is testC");
    18     }
    19 
    20 }

    main 测试方法中创建两个线程访问上述方法:

     1 public class TestLockMain {
     2 
     3     public static void main(String[] args) {
     4         TestLock ts = new TestLock();
     5 
     6         new Thread(new Runnable() {
     7             @Override
     8             public void run() {
     9                 try {
    10                     ts.testA();
    11                 } catch (Exception e) {
    12                     e.printStackTrace();
    13                 }
    14             }
    15         }, "线程1").start();
    16 
    17         new Thread(new Runnable() {
    18             @Override
    19             public void run() {
    20                 try {
    21                     ts.testC();
    22                 } catch (Exception e) {
    23                     e.printStackTrace();
    24                 }
    25             }
    26         }, "线程2").start();
    27 
    28     }
    29 
    30 }

    执行结果:

    线程1:this is testA
    线程2:this is testC
    线程1:this is testB
    线程1:testB is over
    线程1:testA is over
  • 相关阅读:
    设计模式のStrategyPattern(策略模式)----行为模式
    C#反射の一个泛型反射实现的网络请求框架
    C#反射の反射泛型
    C#反射の反射接口
    .Net下的全局异常捕获问题
    设计模式のIOC(控制反转)
    VS2015应用NuGet
    Linux shell脚本的建立与执行
    (转)小小的研究了一下linux下的”注册表“ gconf-editor
    用Visual Studio编辑Linux代码
  • 原文地址:https://www.cnblogs.com/itfeng813/p/14642708.html
Copyright © 2020-2023  润新知