前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java性能测试中两种锁的实现

Java性能测试中两种锁的实现

作者头像
FunTester
发布2020-05-18 14:28:49
3080
发布2020-05-18 14:28:49
举报
文章被收录于专栏:FunTesterFunTester
  • 在使用Java进行性能测试过程中,经常会遇到线程同步代码锁的使用,同步内容的对象、方法、代码块。

同步是使所有并发线程在执行中保持同步的过程。同步避免了由于共享内存视图不一致而导致的内存一致性错误。当方法被声明为同步时,该线程持有监视器或锁定对象为这个方法的对象。如果另一个线程正在执行同步方法,则该线程将被阻塞,直到该线程释放这个锁。

  • 可以通过synchronized在类中的已定义方法或块上使用。

对象级别锁

对象级锁是机制,当我们要同步非静态方法或者非静态代码块,使得只有一个线程就可以在类的给定实例执行的代码块,以确保实例级数据线程安全。对象级别锁定可以通过以下方式完成:

public class DemoClass {

    public synchronized void demoMethod() {
      //搞点事情()
    }
}


public class DemoClass {

    public void demoMethod() {
        synchronized (this) {
            //搞点事情()
        }
    }
}


public class DemoClass {

    private final Object lock = new Object();

    public void demoMethod() {
        synchronized (lock) {
            //搞点事情()
        }
    }
}

类级别锁

类级别锁可防止多个线程synchronized在运行时进入该类的所有可用实例中的任何一个块中。这意味着,如果在运行时有100个实例DemoClass,则一次只能在一个实例中的一个线程上执行一个线程demoMethod(),而所有其他实例将被其他线程锁定。

应该始终执行类级别锁定,以使静态数据线程安全。我们知道static关键字将方法的数据关联到类级别,因此在静态字段或方法上使用锁定使其成为类级别。

public class DemoClass {

    public synchronized static void demoMethod() {
            //搞点事情()
    }
}

public class DemoClass {

    public void demoMethod() {
        synchronized (DemoClass.class) {
            //搞点事情()
        }
    }
}

public class DemoClass {

    private final static Object lock = new Object();

    public void demoMethod() {
        synchronized (lock) {
            //搞点事情()
        }
    }
}

重要说明

  • Java中的同步保证了没有两个线程可以同时或并发执行需要相同锁的同步方法。
  • synchronized关键字只能与方法和代码块一起使用。这些方法或块可以是静态的还是非静态两种。
  • 每当线程进入Java synchronized方法或块时,它都会获得一个锁,而每当它离开同步方法或块时,它将释放该锁。即使线程在完成后或由于任何错误或异常而离开同步方法时,也会释放锁定。
  • Java synchronized关键字本质上是可重入的,这意味着如果一个同步方法调用了另一个需要相同锁的同步方法,则持有锁的当前线程可以进入该方法而无需获取锁。
  • NullPointerException如果在同步块中使用的对象为null,则将引发NullPointerException。例如,在上面的代码示例中,如果将锁初始化为null,则synchronized (lock)将抛出NullPointerException
  • Java中的同步方法使您的应用程序性能降低。
  • 静态同步和非静态同步方法都可能同运行,因为它们锁定在不同的对象上。
  • 根据Java语言规范,不能synchronized在构造函数中使用关键字。
  • 不要在Java中的同步块上的非final字段上进行同步。因为非最终字段的引用可能随时更改,然后不同的线程可能会在不同的对象上进行同步,即完全没有同步。
  • 不要使用String文字,因为它们可能在应用程序中的其他地方被引用,并且可能导致死锁。使用new关键字创建的字符串对象可以安全使用。但是,作为最佳实践,请在我们要保护的共享变量本身上创建一个新的私有作用域Object实例锁。

  • 郑重声明:“FunTester”首发,欢迎关注交流,禁止第三方转载。更多原创文章:FunTester十八张原创专辑,合作请联系Fhaohaizi@163.com
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-05-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 FunTester 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 对象级别锁
  • 类级别锁
  • 重要说明
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档