zoukankan      html  css  js  c++  java
  • “建议127:Lock与synchronized是不一样的问题”实际验证

    近期又一次翻看    “编写高质量代码:改善Java程序的151个建议”  一书的时候看到“建议127”的文章中作者提供的測试用例存在一些值得商榷的地方。

            在使用作者的測试用例得出的结论大概是“ Synchronized  的对象方法调用中。多线程会是相互排斥的方式调用(可理解为线程竞争下依次运行,但不能保证顺序),而使用显示锁即lock.lock的方式下,多线程间是能够并发进行的”。

    (此处的很多其它细节能够看原书的描写叙述)

            细致分析代码后,我发现在代码中用Synchronized  的时候是对字面量  “A” 这个来进行加锁。在java里面,字面量都是会放到常量池中的。所以多个线程调用Synchronized(“A”)这种方法的时候。都会出现线程相互排斥。

    而作者 对于Lock的測试则 使用的一个 类的私有Lock对象进行,那么每一个线程得到是不同的锁(或者都拿到了自己的锁)。则不存在线程间堵塞的问题。假设将Synchronized(“A”)keyword同步的方式改动为Synchronized(obj)即对一个内部的私有对象进行加锁。那么线程间也不存在堵塞的问题了。

            以上是我个人的一个简单结论。有疑问的能够吐槽。我的简版測试代码例如以下:


    public class TestThread {

     public static class TestTask implements Runnable{
      final Object lock1 = new Object();
      private String threadName;
      public TestTask(String threadName){
       this.threadName =threadName;
      }
      @Override
      public void run() {
       System.out.println("===>"+threadName+" will access the lock");
       long b = System.currentTimeMillis();
       synchronized(lock1){//此处能够得出并发运行的结论

        //synchronized("A"){//使用此处的方式则能够得出相互排斥的结论
        try {
         
         System.out.println("===>"+threadName+" run");
         TimeUnit.SECONDS.sleep(5);
        } catch (Exception e) {
         e.printStackTrace();
        }
       }
       long e = System.currentTimeMillis();
       System.out.println("===>"+threadName+" run finished : "+(e-b));
       
      }
      
     };
     public static void main(String[] args) {
      
      Thread t3 = new Thread(new TestTask("t3"));
      Thread t4 = new Thread(new TestTask("t4"));
      Thread t5 = new Thread(new TestTask("t5"));
      t3.start();
      t4.start();
      t5.start();
     }

    ===========================================================

    synchronized("A")的方式 输出例如以下:

    ===>t4 will access the lock
    ===>t3 will access the lock
    ===>t5 will access the lock
    ===>t4 run
    ===>t5 run
    ===>t4 run finished : 5003
    ===>t3 run
    ===>t5 run finished : 10004
    ===>t3 run finished : 15005

    synchronized(lock1)的方式 输出例如以下:

    ===>t5 will access the lock
    ===>t3 will access the lock
    ===>t4 will access the lock
    ===>t3 run
    ===>t5 run
    ===>t4 run
    ===>t3 run finished : 5004
    ===>t4 run finished : 5004
    ===>t5 run finished : 5004

    注意  观察输出从时间


     


  • 相关阅读:
    oauth2的简单介绍以及应用
    springboot查询数据库,js实现二级联动效果
    PHP的简单了解
    JavaScript基础13——面向对象
    JavaScript基础12——运动
    JavaScript基础10——正则
    JavaScript基础09——事件驱动
    JavaScript基础08——DOM
    JavaScript基础07——BOM
    JavaScript基础06——Math对象和日期对象
  • 原文地址:https://www.cnblogs.com/clnchanpin/p/7299418.html
Copyright © 2011-2022 走看看